Skip to content

Commit 10730f9

Browse files
committed
create temporary sqs queue for mns publish notification
1 parent 8e22a92 commit 10730f9

9 files changed

Lines changed: 165 additions & 35 deletions

File tree

infrastructure/instance/.terraform.lock.hcl

Lines changed: 29 additions & 30 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

infrastructure/instance/mns_publisher.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ module "mns_publisher" {
1111
imms_base_path = strcontains(var.sub_environment, "pr-") ? "immunisation-fhir-api/FHIR/R4-${var.sub_environment}" : "immunisation-fhir-api/FHIR/R4"
1212
lambda_kms_encryption_key_arn = data.aws_kms_key.existing_lambda_encryption_key.arn
1313
mns_publisher_resource_name_prefix = "${local.resource_scope}-mns-outbound-events"
14+
mns_test_notifcation_name_prefix = "${local.resource_scope}-mns-test-notification"
1415
secrets_manager_policy_path = "${local.policy_path}/secret_manager.json"
1516
account_id = data.aws_caller_identity.current.account_id
1617
pds_environment = var.pds_environment

infrastructure/instance/modules/mns_publisher/mns_outbound_events_eb_pipe.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,4 @@ resource "aws_pipes_pipe" "mns_outbound_events" {
115115
log_group_arn = aws_cloudwatch_log_group.mns_outbound_events_eb_pipe.arn
116116
}
117117
}
118-
}
118+
}

infrastructure/instance/modules/mns_publisher/mns_publisher_lambda.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ resource "aws_lambda_function" "mns_publisher_lambda" {
192192
environment {
193193
variables = {
194194
SPLUNK_FIREHOSE_NAME = var.splunk_firehose_stream_name
195+
MNS_TEST_QUEUE_URL = aws_sqs_queue.mns_test_notification.url
195196
IMMUNIZATION_ENV = var.resource_scope,
196197
IMMUNIZATION_BASE_PATH = var.imms_base_path
197198
PDS_ENV = var.pds_environment
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Main queue for MNS notification testing
2+
resource "aws_sqs_queue" "mns_test_notification" {
3+
name = "${var.mns_test_notifcation_name_prefix}-queue"
4+
fifo_queue = false
5+
kms_master_key_id = aws_kms_key.mns_outbound_events.arn
6+
visibility_timeout_seconds = 300
7+
}
8+
9+
10+
data "aws_iam_policy_document" "mns_test_notification_sqs_policy" {
11+
statement {
12+
sid = "mns-test-notification-allow-lambda-access"
13+
effect = "Allow"
14+
15+
principals {
16+
type = "AWS"
17+
identifiers = [aws_iam_role.mns_publisher_lambda_exec_role.arn]
18+
}
19+
20+
actions = [
21+
"sqs:SendMessage",
22+
]
23+
24+
resources = [
25+
aws_sqs_queue.mns_test_notification.arn
26+
]
27+
}
28+
}
29+
30+
resource "aws_sqs_queue_policy" "mns_test_notification_sqs" {
31+
queue_url = aws_sqs_queue.mns_test_notification.id
32+
policy = data.aws_iam_policy_document.mns_test_notification_sqs_policy.json
33+
}

infrastructure/instance/modules/mns_publisher/variables.tf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,9 @@ variable "account_id" {
102102
variable "secrets_manager_policy_path" {
103103
type = string
104104
description = "Path to the IAM policy JSON template for Secrets Manager access (e.g., ./policies/secret_manager.json)."
105+
}
106+
107+
variable "mns_test_notifcation_name_prefix" {
108+
type = string
109+
description = "The prefix for the name of resources for testing mns notification"
105110
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import json
2+
import os
3+
4+
import boto3
5+
6+
from common.clients import logger
7+
8+
MNS_TEST_QUEUE_URL = os.getenv("MNS_TEST_QUEUE_URL")
9+
sqs_client = boto3.client("sqs", region_name="eu-west-2")
10+
11+
12+
def send_notification_to_test_queue(mns_payload: dict) -> None:
13+
"""
14+
Send MNS notification payload to test SQS queue as fallback.
15+
Args: payload: MNS notification payload
16+
"""
17+
if not MNS_TEST_QUEUE_URL:
18+
logger.error("MNS_TEST_QUEUE_URL environment variable is not set")
19+
return
20+
21+
try:
22+
response = sqs_client.send_message(
23+
QueueUrl=MNS_TEST_QUEUE_URL,
24+
MessageBody=json.dumps(mns_payload),
25+
MessageAttributes={"source": {"StringValue": "mns-publisher-lambda", "DataType": "String"}},
26+
)
27+
logger.info("Successfully sent notification to test queue", extra={"message_id": response["MessageId"]})
28+
except Exception:
29+
logger.exception("Failed to send to test SQS queue")

lambdas/mns_publisher/src/process_records.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from common.api_clients.mns_setup import get_mns_service
99
from common.clients import logger
1010
from create_notification import create_mns_notification
11+
from mns_test_queue import send_notification_to_test_queue
1112

1213
mns_env = os.getenv("MNS_ENV", "int")
1314

@@ -62,10 +63,12 @@ def process_record(record: SQSMessage, mns_service: MnsService) -> None:
6263
},
6364
)
6465

65-
mns_service.publish_notification(mns_notification_payload)
66-
logger.info("Successfully created MNS notification", extra={"mns_notification_id": notification_id})
67-
68-
return None
66+
try:
67+
mns_service.publish_notification(mns_notification_payload)
68+
logger.info("Successfully created MNS notification", extra={"mns_notification_id": notification_id})
69+
except Exception:
70+
send_notification_to_test_queue(mns_notification_payload)
71+
raise
6972

7073

7174
def extract_trace_ids(record: SQSMessage) -> Tuple[str, str | None]:
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import json
2+
import unittest
3+
from unittest.mock import patch
4+
5+
import boto3
6+
from moto import mock_aws
7+
8+
from mns_test_queue import send_notification_to_test_queue
9+
10+
11+
@mock_aws
12+
class TestMnsSqsQueue(unittest.TestCase):
13+
def setUp(self):
14+
self.sqs = boto3.client("sqs", region_name="eu-west-2")
15+
response = self.sqs.create_queue(QueueName="mns-test-notifications-int")
16+
self.queue_url = response["QueueUrl"]
17+
18+
self.mns_payload = {
19+
"specversion": "1.0",
20+
"id": "236a1d4a-5d69-4fa9-9c7f-e72bf505aa5b",
21+
"source": "https://int.api.service.nhs.uk/immunisation-fhir-api",
22+
"type": "imms-vaccinations-2",
23+
"time": "20260212T174437+00:00",
24+
"subject": "9481152782",
25+
"dataref": "https://int.api.service.nhs.uk/immunisation-fhir-api/Immunization/d058014c-b0fd-4471-8db9-3316175eb825",
26+
"filtering": {
27+
"generalpractitioner": "Y12345",
28+
"sourceorganisation": "B0C4P",
29+
"sourceapplication": "TPP",
30+
"subjectage": 21,
31+
"immunisationtype": "HIB",
32+
"action": "CREATE",
33+
},
34+
}
35+
36+
def test_send_notification_to_queue_success(self):
37+
"""Test successful send to SQS queue with complete payload."""
38+
with patch("mns_test_queue.MNS_TEST_QUEUE_URL", self.queue_url):
39+
send_notification_to_test_queue(self.mns_payload)
40+
41+
messages = self.sqs.receive_message(
42+
QueueUrl=self.queue_url, MaxNumberOfMessages=1, MessageAttributeNames=["All"]
43+
)
44+
45+
self.assertIn("Messages", messages)
46+
self.assertEqual(len(messages["Messages"]), 1)
47+
48+
# Verify message body
49+
mns_payload = json.loads(messages["Messages"][0]["Body"])
50+
attributes = messages["Messages"][0]["MessageAttributes"]
51+
self.assertEqual(attributes["source"]["StringValue"], "mns-publisher-lambda")
52+
53+
self.assertEqual(mns_payload["subject"], "9481152782")
54+
self.assertEqual(mns_payload["filtering"]["generalpractitioner"], "Y12345")
55+
self.assertEqual(mns_payload["filtering"]["sourceorganisation"], "B0C4P")
56+
self.assertEqual(mns_payload["filtering"]["sourceapplication"], "TPP")
57+
self.assertEqual(mns_payload["filtering"]["immunisationtype"], "HIB")
58+
self.assertEqual(mns_payload["filtering"]["action"], "CREATE")
59+
self.assertEqual(mns_payload["filtering"]["subjectage"], 21)

0 commit comments

Comments
 (0)