Skip to content
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
940bbdf
add supplier mock dummy lambda function
Vlasis-Perdikidis Apr 14, 2026
72522b1
correct the name of the supplier_mock lambda
Vlasis-Perdikidis Apr 14, 2026
b709f6a
remove comment from tf file
Vlasis-Perdikidis Apr 14, 2026
241808b
get dummy test to pass
Vlasis-Perdikidis Apr 15, 2026
52da831
disable vale spelling from README
Vlasis-Perdikidis Apr 15, 2026
577b851
correct lambda handler name
Vlasis-Perdikidis Apr 15, 2026
c3bde6b
restore changes
Vlasis-Perdikidis May 28, 2026
c22f094
call patch letter and add variables to parameter store
Vlasis-Perdikidis May 28, 2026
5f4ea2a
merge main
Vlasis-Perdikidis May 28, 2026
c2c9675
resolve final conflicts
Vlasis-Perdikidis May 28, 2026
98d5fb2
refresh package-lock file
Vlasis-Perdikidis May 28, 2026
e7a0433
correct lint and typecheck errors
Vlasis-Perdikidis May 28, 2026
b048bbf
resolve final conflicts
Vlasis-Perdikidis May 28, 2026
92d4c60
re-add @pact-foundation/pact library in run-pact-tests.sh script
Vlasis-Perdikidis May 29, 2026
510c828
install amd64 version of @pact-foundation if missing
Vlasis-Perdikidis May 29, 2026
3199ce5
add ssm:GetParameter permission for supplierId parameter in supplier …
Vlasis-Perdikidis Jun 1, 2026
3bd0da7
merge main
Vlasis-Perdikidis Jun 2, 2026
3045c21
get package-lock in line with main
Vlasis-Perdikidis Jun 2, 2026
6993b09
don't deploy the scheduler by default
Vlasis-Perdikidis Jun 2, 2026
0bf202f
only deploy scheduler resources when flag is set to true
Vlasis-Perdikidis Jun 2, 2026
994de51
deploy the schedule to test it
Vlasis-Perdikidis Jun 2, 2026
cfcdfef
add README with instructions on the supplier-mock lambda
Vlasis-Perdikidis Jun 2, 2026
16651dc
add supplier-mock config in parameter store whith specificationId map…
Vlasis-Perdikidis Jun 3, 2026
da3ea16
fix typecheck
Vlasis-Perdikidis Jun 3, 2026
343c992
remove comment
Vlasis-Perdikidis Jun 3, 2026
f7ac687
correct patch letter request body
Vlasis-Perdikidis Jun 3, 2026
dda6cdf
separate the ssm_parameter to its own file
Vlasis-Perdikidis Jun 8, 2026
ff83654
merge main
Vlasis-Perdikidis Jun 8, 2026
93df971
npm instlal
Vlasis-Perdikidis Jun 8, 2026
7611712
update README for supplier-mock lambda
Vlasis-Perdikidis Jun 8, 2026
02f3f64
address Sid comments
Vlasis-Perdikidis Jun 8, 2026
4fe3b42
move terraform resources into separate folders
Vlasis-Perdikidis Jun 8, 2026
74d6a35
align README structure with the rest
Vlasis-Perdikidis Jun 11, 2026
7c92bea
merge main
Vlasis-Perdikidis Jun 11, 2026
f0e3070
fix zod typecheck error
Vlasis-Perdikidis Jun 12, 2026
1cab254
don't deploy the scheduler by default
Vlasis-Perdikidis Jun 12, 2026
902aa5c
conditionally deploy the aws_iam_policy_document.supplier_mock_lambda…
Vlasis-Perdikidis Jun 12, 2026
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 .env.template
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Your github Personal Access Token (PAT)
PR_NUMBER=prxx # remove if needs to run against main
GITHUB_TOKEN=

# Apigee proxy name to be used for test execution
Expand Down
43 changes: 43 additions & 0 deletions .github/actions/acceptance-tests-component/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Acceptance tests - component
Comment thread
sidnhs marked this conversation as resolved.
Outdated
description: "Run component acceptance tests for this repo"

inputs:
testType:
description: Type of test to run
required: true

targetEnvironment:
description: Name of the environment under test
required: true

targetComponent:
description: Name of the component under test
required: true

runs:
using: "composite"

steps:

- name: Repo setup
uses: ./.github/actions/node-install
with:
GITHUB_TOKEN: ${{ env.GITHUB_TOKEN }}

- name: Fetch terraform output
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5
with:
name: terraform-output-${{ inputs.targetComponent }}

- name: Get Node version
id: nodejs_version
shell: bash
run: |
echo "nodejs_version=$(grep "^nodejs\s" .tool-versions | cut -f2 -d' ')" >> $GITHUB_OUTPUT

- name: Run test - ${{ inputs.testType }}
shell: bash
env:
TARGET_ENVIRONMENT: ${{ inputs.targetEnvironment }}
run: |
make test-${{ inputs.testType }}
1 change: 0 additions & 1 deletion .github/workflows/stage-3-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,6 @@ jobs:
--terraformAction "apply" \
--overrideProjectName "nhs" \
--overrideRoleName "nhs-main-acct-supplier-api-github-deploy"

populate-config:
name: "Populate Supplier Config"
runs-on: ubuntu-latest
Expand Down
3 changes: 3 additions & 0 deletions infrastructure/terraform/components/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ No requirements.
| <a name="input_enable_event_anomaly_detection"></a> [enable\_event\_anomaly\_detection](#input\_enable\_event\_anomaly\_detection) | Enable CloudWatch anomaly detection alarm for SNS message Detects abnormal drops or spikes in event publishing volume. | `bool` | `true` | no |
| <a name="input_enable_event_cache"></a> [enable\_event\_cache](#input\_enable\_event\_cache) | Enable caching of events to an S3 bucket | `bool` | `true` | no |
| <a name="input_enable_sns_delivery_logging"></a> [enable\_sns\_delivery\_logging](#input\_enable\_sns\_delivery\_logging) | Enable SNS Delivery Failure Notifications | `bool` | `true` | no |
| <a name="input_enable_supplier_mock_scheduler"></a> [enable\_supplier\_mock\_scheduler](#input\_enable\_supplier\_mock\_scheduler) | Enable EventBridge Scheduler trigger for supplier mock lambda | `bool` | `false` | no |
| <a name="input_environment"></a> [environment](#input\_environment) | The name of the tfscaffold environment | `string` | n/a | yes |
| <a name="input_event_anomaly_band_width"></a> [event\_anomaly\_band\_width](#input\_event\_anomaly\_band\_width) | The width of the anomaly detection band. Higher values (e.g. 4-6) reduce sensitivity and noise, lower values (e.g. 2-3) increase sensitivity. Recommended: 2-4. | `number` | `4` | no |
| <a name="input_event_anomaly_evaluation_periods"></a> [event\_anomaly\_evaluation\_periods](#input\_event\_anomaly\_evaluation\_periods) | Number of evaluation periods for the anomaly alarm. Each period is defined by event\_anomaly\_period. | `number` | `3` | no |
Expand All @@ -51,6 +52,7 @@ No requirements.
| <a name="input_region"></a> [region](#input\_region) | The AWS Region | `string` | n/a | yes |
| <a name="input_shared_infra_account_id"></a> [shared\_infra\_account\_id](#input\_shared\_infra\_account\_id) | The AWS Account ID of the shared infrastructure account | `string` | `"000000000000"` | no |
| <a name="input_sns_success_logging_sample_percent"></a> [sns\_success\_logging\_sample\_percent](#input\_sns\_success\_logging\_sample\_percent) | Enable SNS Delivery Successful Sample Percentage | `number` | `0` | no |
| <a name="input_supplier_mock_schedule_expression"></a> [supplier\_mock\_schedule\_expression](#input\_supplier\_mock\_schedule\_expression) | Schedule expression for supplier mock scheduler | `string` | `"rate(1 minute)"` | no |
## Modules

| Name | Source | Version |
Expand Down Expand Up @@ -83,6 +85,7 @@ No requirements.
| <a name="module_sqs_letter_updates"></a> [sqs\_letter\_updates](#module\_sqs\_letter\_updates) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/3.1.5/terraform-sqs.zip | n/a |
| <a name="module_sqs_supplier_allocator"></a> [sqs\_supplier\_allocator](#module\_sqs\_supplier\_allocator) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/3.1.5/terraform-sqs.zip | n/a |
| <a name="module_supplier_allocator"></a> [supplier\_allocator](#module\_supplier\_allocator) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/4.0.2/terraform-lambda.zip | n/a |
| <a name="module_supplier_mock"></a> [supplier\_mock](#module\_supplier\_mock) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.29/terraform-lambda.zip | n/a |
| <a name="module_supplier_ssl"></a> [supplier\_ssl](#module\_supplier\_ssl) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.26/terraform-ssl.zip | n/a |
| <a name="module_update_letter_queue"></a> [update\_letter\_queue](#module\_update\_letter\_queue) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/4.0.2/terraform-lambda.zip | n/a |
| <a name="module_upsert_letter"></a> [upsert\_letter](#module\_upsert\_letter) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/4.0.2/terraform-lambda.zip | n/a |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
module "supplier_mock" {
source = "https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.29/terraform-lambda.zip"
Comment thread
sidnhs marked this conversation as resolved.
Outdated

function_name = "supplier_mock"
description = "Mock the behaviour of a supplier"

aws_account_id = var.aws_account_id
component = var.component
environment = var.environment
project = var.project
region = var.region
group = var.group

log_retention_in_days = var.log_retention_in_days
kms_key_arn = module.kms.key_arn

iam_policy_document = {
body = data.aws_iam_policy_document.supplier_mock_lambda.json
}

function_s3_bucket = local.acct.s3_buckets["lambda_function_artefacts"]["id"]
function_code_base_path = local.aws_lambda_functions_dir_path
function_code_dir = "supplier-mock/dist"
function_include_common = true
handler_function_name = "supplierMockHandler"
runtime = "nodejs22.x"
memory = 512
timeout = 29
log_level = var.log_level

force_lambda_code_deploy = var.force_lambda_code_deploy
enable_lambda_insights = false

log_destination_arn = local.destination_arn
log_subscription_role_arn = local.acct.log_subscription_role_arn

lambda_env_vars = merge(local.common_lambda_env_vars, {
ENVIRONMENT = var.environment
GET_LETTERS_FUNCTION_NAME = module.get_letters.function_name
PATCH_LETTER_FUNCTION_NAME = module.patch_letter.function_name
SUPPLIER_MOCK_GET_LETTERS_LIMIT_PARAM_NAME = aws_ssm_parameter.supplier_mock_get_letters_limit.name
SUPPLIER_MOCK_SUPPLIER_ID = aws_ssm_parameter.supplier_mock_supplier_id.name
})
}

resource "aws_ssm_parameter" "supplier_mock_get_letters_limit" {
name = format("/nhs/supapi/supplier-mock/%s/get-letters-limit", var.environment)
description = "Default get_letters limit for supplier mock lambda"
type = "String"
value = "100"

lifecycle {
ignore_changes = [value]
}
}

resource "aws_ssm_parameter" "supplier_mock_supplier_id" {
name = format("/nhs/supapi/supplier-mock/%s/supplier-id", var.environment)
description = "Supplier ID to be used by the supplier mock lambda"
type = "String"
value = "TestSupplier1"

lifecycle {
ignore_changes = [value]
}
}
Comment thread
RossFaulds171 marked this conversation as resolved.
Outdated

data "aws_iam_policy_document" "supplier_mock_lambda" {
statement {
sid = "KMSPermissions"
effect = "Allow"

actions = [
"kms:Decrypt",
"kms:GenerateDataKey",
]

resources = [
module.kms.key_arn, ## Requires shared kms module
]
}

statement {
sid = "AllowInvokeLambda"
effect = "Allow"

actions = [
"lambda:InvokeFunction",
]

resources = [
module.get_letters.function_arn,
module.patch_letter.function_arn
]
}

statement {
sid = "AllowReadSupplierMockLimitParameter"
effect = "Allow"

actions = [
"ssm:GetParameter",
]

resources = [
aws_ssm_parameter.supplier_mock_get_letters_limit.arn,
aws_ssm_parameter.supplier_mock_supplier_id.arn
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
data "aws_iam_policy_document" "supplier_mock_scheduler_trust_policy" {
statement {
sid = "AllowSchedulerAssumeRole"
effect = "Allow"

actions = [
"sts:AssumeRole",
]

principals {
type = "Service"

identifiers = [
"scheduler.amazonaws.com",
]
}
}
}

resource "aws_iam_role" "supplier_mock_scheduler" {
name = "${local.csi}-supplier-mock-scheduler"
Comment thread
Vlasis-Perdikidis marked this conversation as resolved.
Outdated
description = "Allows EventBridge Scheduler to invoke supplier mock lambda"
assume_role_policy = data.aws_iam_policy_document.supplier_mock_scheduler_trust_policy.json
}

data "aws_iam_policy_document" "supplier_mock_scheduler_invoke_policy" {
statement {
sid = "AllowInvokeSupplierMockLambda"
effect = "Allow"

actions = [
"lambda:InvokeFunction",
]

resources = [
module.supplier_mock.function_arn,
]
}
}

resource "aws_iam_policy" "supplier_mock_scheduler_invoke_policy" {
name = "${local.csi}-supplier-mock-scheduler-invoke"
policy = data.aws_iam_policy_document.supplier_mock_scheduler_invoke_policy.json
}

resource "aws_iam_role_policy_attachment" "supplier_mock_scheduler_invoke_policy" {
role = aws_iam_role.supplier_mock_scheduler.name
policy_arn = aws_iam_policy.supplier_mock_scheduler_invoke_policy.arn
}

resource "aws_scheduler_schedule" "supplier_mock" {
Comment thread
sidnhs marked this conversation as resolved.
Outdated
name = "${local.csi}-supplier-mock"
description = "Scheduled trigger for supplier mock lambda"
state = var.enable_supplier_mock_scheduler ? "ENABLED" : "DISABLED"

flexible_time_window {
mode = "OFF"
}

schedule_expression = var.supplier_mock_schedule_expression

target {
arn = module.supplier_mock.function_arn
role_arn = aws_iam_role.supplier_mock_scheduler.arn
input = jsonencode({
source = "eventbridge-scheduler"
})
}
}
12 changes: 12 additions & 0 deletions infrastructure/terraform/components/api/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,18 @@ variable "enable_alarms" {
default = true
}

variable "enable_supplier_mock_scheduler" {
type = bool
description = "Enable EventBridge Scheduler trigger for supplier mock lambda"
default = false
}

variable "supplier_mock_schedule_expression" {
type = string
description = "Schedule expression for supplier mock scheduler"
default = "rate(1 minute)"
}

variable "enable_event_anomaly_detection" {
type = bool
description = "Enable CloudWatch anomaly detection alarm for SNS message Detects abnormal drops or spikes in event publishing volume."
Expand Down
5 changes: 5 additions & 0 deletions lambdas/supplier-mock/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
coverage
node_modules
dist
.reports
.aws-sam
69 changes: 69 additions & 0 deletions lambdas/supplier-mock/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
export const baseJestConfig = {
preset: "ts-jest",
extensionsToTreatAsEsm: [".ts"],
transform: {
"^.+\\.ts$": [
"ts-jest",
{
useESM: true,
},
],
},
transformIgnorePatterns: [
"node_modules/(?!(@nhsdigital/nhs-notify-event-schemas-supplier-config)/)",
],

// Automatically clear mock calls, instances, contexts and results before every test
clearMocks: true,

// Indicates whether the coverage information should be collected while executing the test
collectCoverage: true,

// The directory where Jest should output its coverage files
coverageDirectory: "./.reports/unit/coverage",

// Indicates which provider should be used to instrument code for coverage
coverageProvider: "babel",

coverageThreshold: {
global: {
branches: 100,
functions: 100,
lines: 100,
statements: -10,
},
},

coveragePathIgnorePatterns: ["/__tests__/"],
testPathIgnorePatterns: [".build"],
testMatch: ["**/?(*.)+(spec|test).[jt]s?(x)"],

// Use this configuration option to add custom reporters to Jest
reporters: [
"default",
[
"jest-html-reporter",
{
pageTitle: "Test Report",
outputPath: "./.reports/unit/test-report.html",
includeFailureMsg: true,
},
],
],

// The test environment that will be used for testing
testEnvironment: "jsdom",
};

const utilsJestConfig = {
...baseJestConfig,

testEnvironment: "node",

coveragePathIgnorePatterns: [
...(baseJestConfig.coveragePathIgnorePatterns ?? []),
"zod-validators.ts",
],
};

export default utilsJestConfig;
22 changes: 22 additions & 0 deletions lambdas/supplier-mock/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"dependencies": {
"@aws-sdk/client-api-gateway": "^3.1030.0",
"@aws-sdk/client-lambda": "^3.1030.0",
"@aws-sdk/client-ssm": "^3.1054.0",
"@internal/helpers": "^0.1.0",
"aws-embedded-metrics": "^4.2.1",
"aws-lambda": "^1.0.7",
"pino": "^10.3.1",
"zod": "^4.3.6"
},
"name": "nhs-notify-supplier-api-supplier-mock",
"private": true,
"scripts": {
"lambda-build": "rm -rf dist && npx esbuild --bundle --minify --sourcemap --target=es2020 --platform=node --loader:.node=file --entry-names=[name] --outdir=dist src/index.ts",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"test:unit": "jest",
"typecheck": "tsc --noEmit"
},
"version": "0.0.1"
}
Loading
Loading