Skip to content

Commit 024ff02

Browse files
[PRMP-168] Update lambda handler and service (#843)
Co-authored-by: adamwhitingnhs <[email protected]>
1 parent a71fcb2 commit 024ff02

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1368
-405
lines changed

.github/workflows/base-lambdas-reusable-deploy-all.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,20 @@ jobs:
6262
secrets:
6363
AWS_ASSUME_ROLE: ${{ secrets.AWS_ASSUME_ROLE }}
6464

65+
deploy_update_document_reference_lambda:
66+
name: Deploy update_document_reference_lambda
67+
uses: ./.github/workflows/base-lambdas-reusable-deploy.yml
68+
with:
69+
environment: ${{ inputs.environment}}
70+
python_version: ${{ inputs.python_version }}
71+
build_branch: ${{ inputs.build_branch}}
72+
sandbox: ${{ inputs.sandbox }}
73+
lambda_handler_name: update_document_reference_handler
74+
lambda_aws_name: UpdateDocRefLambda
75+
lambda_layer_names: "core_lambda_layer"
76+
secrets:
77+
AWS_ASSUME_ROLE: ${{ secrets.AWS_ASSUME_ROLE }}
78+
6579
deploy_search_patient_details_lambda:
6680
name: Deploy search_patient_details_lambda
6781
uses: ./.github/workflows/base-lambdas-reusable-deploy.yml

app/cypress/support/feature_flags.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ export const defaultFeatureFlags: FeatureFlags = {
66
uploadLloydGeorgeWorkflowEnabled: true,
77
uploadArfWorkflowEnabled: true,
88
uploadLambdaEnabled: true,
9+
uploadDocumentIteration2Enabled: true,
910
};

app/src/types/generic/endpoints.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export enum endpoints {
66
PATIENT_SEARCH = '/SearchPatient',
77

88
DOCUMENT_SEARCH = '/SearchDocumentReferences',
9-
DOCUMENT_UPLOAD = '/CreateDocumentReference',
9+
DOCUMENT_UPLOAD = '/DocumentReference',
1010
DOCUMENT_PRESIGN = '/DocumentManifest',
1111

1212
LLOYDGEORGE_STITCH = '/LloydGeorgeStitch',

lambdas/enums/feature_flags.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ class FeatureFlags(StrEnum):
99
LLOYD_GEORGE_VALIDATION_STRICT_MODE_ENABLED = (
1010
"lloydGeorgeValidationStrictModeEnabled"
1111
)
12+
UPLOAD_DOCUMENT_ITERATION_2_ENABLED = "uploadDocumentIteration2Enabled"

lambdas/enums/lambda_error.py

Lines changed: 29 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -60,116 +60,74 @@ def create_error_body(self, params: Optional[dict] = None, **kwargs) -> str:
6060
"fhir_coding": UKCoreSpineError.VALIDATION_ERROR,
6161
}
6262

63-
"""
64-
Errors for CreateDocumentRefException
65-
"""
66-
CreateDocNoBody = {"err_code": "CDR_4001", "message": "Missing event body"}
67-
CreateDocPayload = {"err_code": "CDR_4002", "message": "Invalid json in body"}
68-
CreateDocProps = {
69-
"err_code": "CDR_4003",
70-
"message": "Request body missing some properties",
71-
}
72-
CreateDocFiles = {"err_code": "CDR_4004", "message": "Invalid files or id"}
73-
CreateDocNoParse = {
74-
"err_code": "CDR_4005",
75-
"message": "Failed to parse document upload request data",
76-
"fhir_coding": UKCoreSpineError.VALIDATION_ERROR,
77-
}
78-
CreateDocNoType = {
79-
"err_code": "CDR_4006",
80-
"message": "Failed to parse document upload request data due to missing document type",
81-
"fhir_coding": UKCoreSpineError.MISSING_VALUE,
82-
}
83-
CreateDocInvalidType = {
84-
"err_code": "CDR_4007",
85-
"message": "Failed to parse document upload request data due to invalid document type",
86-
"fhir_coding": UKCoreSpineError.INVALID_VALUE,
87-
}
88-
CreateDocRecordAlreadyInPlace = {
89-
"err_code": "CDR_4008",
90-
"message": "The patient already has a full set of record.",
91-
}
92-
CreateDocRefOdsCodeNotAllowed = {
93-
"err_code": "CDR_4009",
94-
"message": "ODS code does not match any of the allowed.",
95-
}
96-
CreateDocPresign = {
97-
"err_code": "CDR_5001",
98-
"message": "An error occurred when creating pre-signed url for document reference",
99-
}
100-
CreateDocUploadInternalError = {
101-
"err_code": "CDR_5002",
102-
"message": "An error occurred when creating pre-signed url for document reference",
103-
}
104-
CreatePatientSearchInvalid = {
105-
"err_code": "CDR_5003",
106-
"message": "Failed to validate patient",
107-
"fhir_coding": UKCoreSpineError.VALIDATION_ERROR,
108-
}
10963

11064
"""
111-
Errors for UpdateDocumentRefException
65+
Errors for /DocumentReference
11266
"""
113-
UpdateDocNoBody = {
114-
"err_code": "UDR_4001",
67+
DocRefNoBody = {
68+
"err_code": "DR_4001",
11569
"message": "Missing event body",
11670
"fhir_coding": FhirIssueCoding.REQUIRED,
11771
}
118-
UpdateDocPayload = {
119-
"err_code": "UDR_4002",
72+
DocRefPayload = {
73+
"err_code": "DR_4002",
12074
"message": "Invalid json in body",
12175
"fhir_coding": FhirIssueCoding.INVALID,
12276
}
123-
UpdateDocProps = {
124-
"err_code": "UDR_4003",
77+
DocRefProps = {
78+
"err_code": "DR_4003",
12579
"message": "Request body missing some properties",
12680
"fhircoding": FhirIssueCoding.REQUIRED
12781
}
128-
UpdateDocFiles = {
129-
"err_code": "UDR_4004",
82+
DocRefInvalidFiles = {
83+
"err_code": "DR_4004",
13084
"message": "Invalid files or id",
13185
"fhir_coding": FhirIssueCoding.INVALID
13286
}
133-
UpdateDocNoParse = {
134-
"err_code": "UDR_4005",
87+
DocRefNoParse = {
88+
"err_code": "DR_4005",
13589
"message": "Failed to parse document upload request data",
13690
"fhir_coding": UKCoreSpineError.VALIDATION_ERROR,
13791
}
138-
UpdateDocNoType = {
139-
"err_code": "UDR_4006",
92+
DocRefNoType = {
93+
"err_code": "DR_4006",
14094
"message": "Failed to parse document upload request data due to missing document type",
14195
"fhir_coding": UKCoreSpineError.MISSING_VALUE,
14296
}
143-
UpdateDocInvalidType = {
144-
"err_code": "UDR_4007",
97+
DocRefInvalidType = {
98+
"err_code": "DR_4007",
14599
"message": "Failed to parse document upload request data due to invalid document type",
146100
"fhir_coding": UKCoreSpineError.INVALID_VALUE,
147101
}
148-
UpdateDocRecordAlreadyInPlace = {
149-
"err_code": "UDR_4008",
102+
DocRefRecordAlreadyInPlace = {
103+
"err_code": "DR_4008",
150104
"message": "The patient already has a full set of record.",
151105
"fhir_coding": FhirIssueCoding.DUPLICATE,
152106
}
153-
UpdateDocRefOdsCodeNotAllowed = {
154-
"err_code": "UDR_4009",
107+
DocRefOdsCodeNotAllowed = {
108+
"err_code": "DR_4009",
155109
"message": "ODS code does not match any of the allowed.",
156110
"fhir_coding": FhirIssueCoding.INVALID,
157111
}
158-
UpdateDocPresign = {
159-
"err_code": "UDR_5001",
112+
DocRefPresign = {
113+
"err_code": "DR_5001",
160114
"message": "An error occurred when creating pre-signed url for document reference",
161115
"fhir_coding": FhirIssueCoding.EXCEPTION,
162116
}
163-
UpdateDocUploadInternalError = {
164-
"err_code": "UDR_5002",
117+
DocRefUploadInternalError = {
118+
"err_code": "DR_5002",
165119
"message": "An error occurred when creating pre-signed url for document reference",
166120
"fhir_coding": FhirIssueCoding.EXCEPTION
167121
}
168-
UpdatePatientSearchInvalid = {
169-
"err_code": "UDR_5003",
122+
DocRefPatientSearchInvalid = {
123+
"err_code": "DR_5003",
170124
"message": "Failed to validate patient",
171125
"fhir_coding": UKCoreSpineError.VALIDATION_ERROR,
172126
}
127+
128+
"""
129+
Errors for Update via /DocumentReference
130+
"""
173131
UpdateDocVersionMismatch = {
174132
"err_code": "UDR_5004",
175133
"message": "Document reference version did not match current document version",

lambdas/enums/logging_app_interaction.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class LoggingAppInteraction(Enum):
1010
DOWNLOAD_RECORD = "Download a record"
1111
DELETE_RECORD = "Delete a record"
1212
UPLOAD_RECORD = "Upload a record"
13+
UPDATE_RECORD = "Update a record"
1314
STITCH_RECORD = "Stitch a record"
1415
ODS_REPORT = "Download an ODS report"
1516
LOGOUT = "Logout"

lambdas/handlers/authoriser_handler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def lambda_handler(event, context):
4242
if event.get("methodArn") is None:
4343
return {"Error": "methodArn is not defined"}
4444
_, _, _, region, aws_account_id, api_gateway_arn = event.get("methodArn").split(":")
45-
api_id, stage, _http_verb, _resource_name = api_gateway_arn.split("/")
45+
api_id, stage, _http_verb, _resource_name = api_gateway_arn.split("/", 3)
4646
path = "/" + _resource_name
4747

4848
policy = AuthPolicy(aws_account_id)
Lines changed: 20 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import json
22
import os
33
import sys
4-
from json import JSONDecodeError
54

65
from enums.feature_flags import FeatureFlags
7-
from enums.lambda_error import LambdaError
86
from enums.logging_app_interaction import LoggingAppInteraction
97
from services.create_document_reference_service import CreateDocumentReferenceService
108
from services.feature_flags_service import FeatureFlagService
@@ -14,9 +12,12 @@
1412
from utils.decorators.override_error_check import override_error_check
1513
from utils.decorators.set_audit_arg import set_request_context_for_logging
1614
from utils.decorators.validate_patient_id import validate_patient_id
17-
from utils.lambda_exceptions import CreateDocumentRefException, FeatureFlagsException
1815
from utils.lambda_response import ApiGatewayResponse
1916
from utils.request_context import request_context
17+
from utils.document_reference_common_validations import (
18+
process_event_body,
19+
validate_matching_patient_ids,
20+
)
2021

2122
sys.path.append(os.path.join(os.path.dirname(__file__)))
2223

@@ -42,64 +43,30 @@
4243
def lambda_handler(event, context):
4344
request_context.app_interaction = LoggingAppInteraction.UPLOAD_RECORD.value
4445

45-
feature_flag_service = FeatureFlagService()
46-
upload_flag_name = FeatureFlags.UPLOAD_LAMBDA_ENABLED.value
47-
upload_lambda_enabled_flag_object = feature_flag_service.get_feature_flags_by_flag(
48-
upload_flag_name
46+
FeatureFlagService().validate_feature_flag(
47+
FeatureFlags.UPLOAD_LAMBDA_ENABLED.value
4948
)
5049

51-
if not upload_lambda_enabled_flag_object[upload_flag_name]:
52-
logger.info("Feature flag not enabled, event will not be processed")
53-
raise FeatureFlagsException(404, LambdaError.FeatureFlagDisabled)
54-
5550
logger.info("Starting document reference creation process")
56-
nhs_number_query_string = event["queryStringParameters"]["patientId"]
57-
nhs_number_body, doc_list = processing_event_details(event)
58-
if nhs_number_body != nhs_number_query_string:
59-
logger.warning(
60-
"Received nhs number query string does not match event's body nhs number"
61-
)
62-
raise CreateDocumentRefException(400, LambdaError.PatientIdMismatch)
63-
request_context.patient_nhs_no = nhs_number_query_string
51+
nhs_number_query = event["queryStringParameters"]["patientId"]
52+
53+
nhs_number_body, doc_list = process_event_body(
54+
event
55+
)
56+
57+
validate_matching_patient_ids(
58+
nhs_number_query, nhs_number_body
59+
)
60+
61+
request_context.patient_nhs_no = nhs_number_query
6462

6563
logger.info("Processed upload documents from request")
66-
docs_services = CreateDocumentReferenceService()
64+
create_doc_ref_service = CreateDocumentReferenceService()
6765

68-
url_references = docs_services.create_document_reference_request(
69-
nhs_number_query_string, doc_list
66+
url_references = create_doc_ref_service.create_document_reference_request(
67+
nhs_number_query, doc_list
7068
)
7169

7270
return ApiGatewayResponse(
7371
200, json.dumps(url_references), "POST"
7472
).create_api_gateway_response()
75-
76-
77-
def processing_event_details(event):
78-
failed_message = "Create document reference failed"
79-
80-
try:
81-
body = json.loads(event["body"])
82-
nhs_number = body["subject"]["identifier"]["value"]
83-
84-
if not body or not isinstance(body, dict):
85-
logger.error(
86-
f"{LambdaError.CreateDocNoBody.to_str()}",
87-
{"Result": failed_message},
88-
)
89-
raise CreateDocumentRefException(400, LambdaError.CreateDocNoBody)
90-
91-
doc_list = body["content"][0]["attachment"]
92-
return nhs_number, doc_list
93-
94-
except (JSONDecodeError, AttributeError) as e:
95-
logger.error(
96-
f"{LambdaError.CreateDocPayload.to_str()}: {str(e)}",
97-
{"Result": failed_message},
98-
)
99-
raise CreateDocumentRefException(400, LambdaError.CreateDocPayload)
100-
except (KeyError, TypeError) as e:
101-
logger.error(
102-
f"{LambdaError.CreateDocProps.to_str()}: {str(e)}",
103-
{"Result": failed_message},
104-
)
105-
raise CreateDocumentRefException(400, LambdaError.CreateDocProps)

lambdas/handlers/post_fhir_document_reference_handler.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
)
44
from utils.audit_logging_setup import LoggingService
55
from utils.decorators.handle_lambda_exceptions import handle_lambda_exceptions_fhir
6-
from utils.lambda_exceptions import CreateDocumentRefException
6+
from utils.lambda_exceptions import DocumentRefException
77
from utils.lambda_response import ApiGatewayResponse
88

99
logger = LoggingService(__name__)
@@ -38,7 +38,7 @@ def lambda_handler(event, context):
3838
status_code=200, body=fhir_response, methods="POST"
3939
).create_api_gateway_response()
4040

41-
except CreateDocumentRefException as exception:
41+
except DocumentRefException as exception:
4242
logger.error(f"Error processing FHIR document reference: {str(exception)}")
4343
return ApiGatewayResponse(
4444
status_code=exception.status_code,

0 commit comments

Comments
 (0)