Skip to content

Commit e0b79b8

Browse files
authored
Merge pull request #365 from NHSDigital/AMB-2144-mesh-integration
Amb 2144 mesh integration
2 parents f418f80 + 88b1162 commit e0b79b8

File tree

17 files changed

+499
-4
lines changed

17 files changed

+499
-4
lines changed

.github/workflows/sonarcloud.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,14 @@ jobs:
7878
pip install poetry==1.8.4 moto==4.2.11 coverage redis botocore==1.35.49 simplejson responses structlog fhir.resources jsonpath_ng pydantic==1.10.13 requests aws-lambda-typing cffi pyjwt boto3-stubs-lite[dynamodb]~=1.26.90 python-stdnum==1.20
7979
poetry run coverage run --source=backend -m unittest discover -s backend || echo "fhir-api tests failed" >> failed_tests.txt
8080
poetry run coverage xml -o sonarcloud-coverage.xml
81+
82+
- name: Run unittest with coverage-mesh-processor
83+
id: meshprocessor
84+
continue-on-error: true
85+
run: |
86+
pip install poetry==1.8.4 moto==4.2.11 coverage redis botocore==1.35.49 simplejson responses structlog fhir.resources jsonpath_ng pydantic==1.10.13 requests aws-lambda-typing cffi pyjwt boto3-stubs-lite[dynamodb]~=1.26.90 python-stdnum==1.20
87+
poetry run coverage run --source=meshfileprocessor -m unittest discover -s meshfileprocessor || echo "meshfileprocessor tests failed" >> failed_tests.txt
88+
poetry run coverage xml -o sonarcloud-meshfileprocessor-coverage.xml
8189
8290
- name: Run Test Failure Summary
8391
id: check_failure

filenameprocessor/src/file_key_validation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def validate_file_key(file_key: str) -> tuple[str, str]:
5454
and version in Constants.VALID_VERSIONS
5555
and supplier # Note that if supplier could be identified, this also implies that ODS code is valid
5656
and is_valid_datetime(timestamp)
57-
and extension == "CSV"
57+
and ((extension == "CSV") or (extension == "DAT")) # The DAT extension has been added for MESH file processing
5858
):
5959
raise InvalidFileKeyError("Initial file validation failed: invalid file key")
6060

filenameprocessor/tests/test_file_key_validation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ def test_validate_file_key(self):
9393
# File key with missing timestamp
9494
(VALID_FLU_EMIS_FILE_KEY.replace("20000101T00000001", ""), invalid_file_key_error_message),
9595
# File key with incorrect extension
96-
(VALID_FLU_EMIS_FILE_KEY.replace(".csv", ".dat"), invalid_file_key_error_message),
96+
(VALID_FLU_EMIS_FILE_KEY.replace(".csv", ".xlsx"), invalid_file_key_error_message),
9797
]
9898

9999
for file_key, expected_result in test_cases_for_failure_scenarios:

mesh-infra/main.tf

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
terraform {
2+
required_providers {
3+
aws = {
4+
source = "hashicorp/aws"
5+
version = "~> 5"
6+
}
7+
}
8+
backend "s3" {
9+
region = "eu-west-2"
10+
key = "state"
11+
}
12+
required_version = ">= 1.5.0"
13+
}
14+
15+
16+
17+
data "aws_vpc" "default" {
18+
default = true
19+
}
20+
data "aws_subnets" "default" {
21+
filter {
22+
name = "vpc-id"
23+
values = [data.aws_vpc.default.id]
24+
}
25+
}
26+
27+
module "mesh" {
28+
source = "git::https://github.com/nhsdigital/terraform-aws-mesh-client.git//module?ref=v2.1.5"
29+
30+
name_prefix = "local-immunisation"
31+
mesh_env = "integration"
32+
subnet_ids = data.aws_subnets.default.ids
33+
34+
mailbox_ids = ["X26OT303"]
35+
verify_ssl = "true"
36+
get_message_max_concurrency = 10
37+
compress_threshold = 1 * 1024 * 1024
38+
handshake_schedule = "rate(24 hours)"
39+
40+
account_id = 345594581768
41+
}

meshfileprocessor/Dockerfile

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
FROM public.ecr.aws/lambda/python:3.10 AS base
2+
3+
# Create a non-root user with a specific UID and GID
4+
RUN mkdir -p /home/appuser && \
5+
echo 'appuser:x:1001:1001::/home/appuser:/sbin/nologin' >> /etc/passwd && \
6+
echo 'appuser:x:1001:' >> /etc/group && \
7+
chown -R 1001:1001 /home/appuser && pip install "poetry~=1.5.0"
8+
9+
# Install Poetry as root
10+
COPY poetry.lock pyproject.toml README.md ./
11+
RUN poetry config virtualenvs.create false && poetry install --no-interaction --no-ansi --no-root --only main
12+
13+
# -----------------------------
14+
# FROM base AS test
15+
# COPY src src
16+
# COPY tests tests
17+
# RUN poetry install --no-interaction --no-ansi --no-root && \
18+
# pytest --disable-warnings tests
19+
20+
# -----------------------------
21+
FROM base AS build
22+
23+
COPY src .
24+
RUN chmod 644 $(find . -type f) && chmod 755 $(find . -type d)
25+
# Switch to the non-root user for running the container
26+
USER 1001:1001
27+
CMD ["converter.lambda_handler"]

meshfileprocessor/Makefile

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
build:
2+
docker build -t mesh-lambda-build .
3+
4+
package:build
5+
mkdir -p build
6+
docker run --rm -v $(shell pwd)/build:/build mesh-lambda-build
7+
# test:
8+
# python -m unittest
9+
10+
# coverage run:
11+
# coverage run -m unittest discover
12+
13+
# coverage report:
14+
# coverage report -m
15+
16+
# coverage html:
17+
# coverage html
18+
19+
.PHONY: build package

meshfileprocessor/README.md

Whitespace-only changes.

meshfileprocessor/pyproject.toml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
[tool.poetry]
2+
name = "meshconverter"
3+
version = "0.1.0"
4+
description = ""
5+
authors = ["Your Name <[email protected]>"]
6+
readme = "README.md"
7+
packages = [{include = "src"}]
8+
9+
[tool.poetry.dependencies]
10+
python = "~3.10"
11+
"fhir.resources" = "~7.0.2"
12+
boto3 = "~1.26.90"
13+
boto3-stubs-lite = {extras = ["dynamodb"], version = "~1.26.90"}
14+
aws-lambda-typing = "~2.18.0"
15+
moto = "~4.2.11"
16+
requests = "~2.31.0"
17+
responses = "~0.24.1"
18+
pydantic = "~1.10.13"
19+
pyjwt = "~2.8.0"
20+
cryptography = "~42.0.4"
21+
cffi = "~1.16.0"
22+
jsonpath-ng = "^1.6.0"
23+
simplejson = "^3.19.2"
24+
structlog = "^24.1.0"
25+
pandas = "^2.2.3"
26+
freezegun = "^1.5.1"
27+
28+
[build-system]
29+
requires = ["poetry-core ~= 1.5.0"]
30+
31+
build-backend = "poetry.core.masonry.api"

meshfileprocessor/src/__init__.py

Whitespace-only changes.

meshfileprocessor/src/converter.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import boto3
2+
import os
3+
4+
5+
def lambda_handler(event, context):
6+
s3 = boto3.client('s3')
7+
8+
# Destination bucket name
9+
destination_bucket = os.getenv("Destination_BUCKET_NAME")
10+
11+
for record in event["Records"]:
12+
bucket_name = record["s3"]["bucket"]["name"]
13+
file_key = record["s3"]["object"]["key"]
14+
copy_source = {
15+
'Bucket': record["s3"]["bucket"]["name"],
16+
'Key': record["s3"]["object"]["key"]
17+
}
18+
19+
# Read the .dat file from S3
20+
dat_obj = s3.get_object(Bucket=bucket_name, Key=file_key)
21+
22+
# Update the filename from Metadata
23+
file_name = ensure_dat_extension(dat_obj['Metadata'].get('mex-filename', None))
24+
25+
s3.copy_object(CopySource=copy_source, Bucket=destination_bucket, Key=file_name)
26+
27+
return {
28+
'statusCode': 200,
29+
'body': 'Files converted and uploaded successfully!'
30+
}
31+
32+
33+
def ensure_dat_extension(file_name):
34+
if '.' in file_name:
35+
# Split the filename and extension
36+
base_name, extension = file_name.rsplit('.', 1)
37+
38+
# Check if the extension is not 'dat'
39+
if extension != 'dat':
40+
file_name = f"{base_name}.dat"
41+
else:
42+
file_name += '.dat'
43+
44+
return file_name

0 commit comments

Comments
 (0)