Skip to content

Commit 374e073

Browse files
Merge branch 'develop' into feature/eema1-NRL-497-moveCountToSearch
Conflicts: api/consumer/searchDocumentReference/tests/test_search_document_reference_consumer.py api/consumer/searchPostDocumentReference/tests/test_search_post_document_reference_consumer.py
2 parents 6ea2e0e + 7c46e08 commit 374e073

File tree

16 files changed

+334
-10
lines changed

16 files changed

+334
-10
lines changed

api/consumer/searchDocumentReference/tests/test_search_document_reference_consumer.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
from unittest.mock import patch
23

34
from moto import mock_aws
45

@@ -760,7 +761,10 @@ def test_search_document_reference_filters_by_summary_count(
760761

761762
@mock_aws
762763
@mock_repository
763-
def test_search_document_reference_invalid_json(repository: DocumentPointerRepository):
764+
@patch("api.consumer.searchDocumentReference.search_document_reference.logger")
765+
def test_search_document_reference_invalid_json(
766+
mock_logger, repository: DocumentPointerRepository
767+
):
764768
doc_ref = load_document_reference("Y05868-736253002-Valid")
765769
doc_pointer = DocumentPointer.from_document_reference(doc_ref)
766770
repository.create(doc_pointer)
@@ -823,3 +827,7 @@ def test_search_document_reference_invalid_json(repository: DocumentPointerRepos
823827
{"resource": expected_operation_outcome},
824828
],
825829
}
830+
831+
assert any(
832+
call[0][0].name == "CONSEARCH005" for call in mock_logger.log.call_args_list
833+
)

api/consumer/searchPostDocumentReference/tests/test_search_post_document_reference_consumer.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
from unittest.mock import patch
23

34
from moto import mock_aws
45

@@ -522,8 +523,9 @@ def test_search_document_reference_filters_by_summary_count(
522523

523524
@mock_aws
524525
@mock_repository
526+
@patch("api.consumer.searchPostDocumentReference.search_post_document_reference.logger")
525527
def test_search_post_document_reference_invalid_json_adds_operation_outcome(
526-
repository: DocumentPointerRepository,
528+
mock_logger, repository: DocumentPointerRepository
527529
):
528530
doc_ref = load_document_reference("Y05868-736253002-Valid")
529531
doc_pointer = DocumentPointer.from_document_reference(doc_ref)
@@ -589,3 +591,7 @@ def test_search_post_document_reference_invalid_json_adds_operation_outcome(
589591
{"resource": expected_operation_outcome},
590592
],
591593
}
594+
595+
assert any(
596+
call[0][0].name == "CONPOSTSEARCH005" for call in mock_logger.log.call_args_list
597+
)

api/producer/searchDocumentReference/tests/test_search_document_reference_producer.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
from unittest.mock import patch
23

34
from moto import mock_aws
45

@@ -457,7 +458,10 @@ def test_search_document_reference_filters_by_pointer_types(
457458

458459
@mock_aws
459460
@mock_repository
460-
def test_search_document_reference_invalid_json(repository: DocumentPointerRepository):
461+
@patch("api.producer.searchDocumentReference.search_document_reference.logger")
462+
def test_search_document_reference_invalid_json(
463+
mock_logger, repository: DocumentPointerRepository
464+
):
461465
doc_ref = load_document_reference("Y05868-736253002-Valid")
462466
doc_pointer = DocumentPointer.from_document_reference(doc_ref)
463467
repository.create(doc_pointer)
@@ -514,3 +518,7 @@ def test_search_document_reference_invalid_json(repository: DocumentPointerRepos
514518
{"resource": expected_operation_outcome},
515519
],
516520
}
521+
522+
assert any(
523+
call[0][0].name == "PROSEARCH005" for call in mock_logger.log.call_args_list
524+
)

api/producer/searchPostDocumentReference/tests/test_search_post_document_reference_producer.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
from unittest.mock import patch
23

34
from moto import mock_aws
45

@@ -474,7 +475,9 @@ def test_search_document_reference_filters_by_pointer_types(
474475

475476
@mock_aws
476477
@mock_repository
478+
@patch("api.producer.searchPostDocumentReference.search_post_document_reference.logger")
477479
def test_search_post_document_reference_invalid_json_adds_operation_outcome(
480+
mock_logger,
478481
repository: DocumentPointerRepository,
479482
):
480483
doc_ref = load_document_reference("Y05868-736253002-Valid")
@@ -535,3 +538,7 @@ def test_search_post_document_reference_invalid_json_adds_operation_outcome(
535538
{"resource": expected_operation_outcome},
536539
],
537540
}
541+
542+
assert any(
543+
call[0][0].name == "PROPOSTSEARCH005" for call in mock_logger.log.call_args_list
544+
)

layer/nrlf/core/log_references.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ class _Reference:
77
level: str
88
message: str
99

10+
# WARNING: This makes all _Reference objects unequal unless they are the same instance.
11+
# It's fine for our use case, but be cautious if you compare _Reference objects.
12+
def __eq__(self, other):
13+
return self is other
14+
15+
def __hash__(self):
16+
return id(self)
17+
1018

1119
class LogReference(Enum):
1220
# Request Handler Logs

terraform/infrastructure/api_gateway.tf

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ module "consumer__gateway" {
1010
method_readDocumentReference = "arn:aws:apigateway:eu-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:eu-west-2:${local.aws_account_id}:function:${substr("${local.prefix}--api--consumer--readDocumentReference", 0, 64)}/invocations"
1111
method_status = "arn:aws:apigateway:eu-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:eu-west-2:${local.aws_account_id}:function:${substr("${local.prefix}--api--consumer--status", 0, 64)}/invocations"
1212
}
13+
endpoint_allowed_methods = {
14+
"/DocumentReference" = "GET",
15+
"/DocumentReference/{id}" = "GET"
16+
}
1317
kms_key_id = module.kms__cloudwatch.kms_arn
1418
domain = local.apis.domain
1519
path = local.apis.consumer.path
@@ -35,7 +39,10 @@ module "producer__gateway" {
3539
method_deleteDocumentReference = "arn:aws:apigateway:eu-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:eu-west-2:${local.aws_account_id}:function:${substr("${local.prefix}--api--producer--deleteDocumentReference", 0, 64)}/invocations"
3640
method_status = "arn:aws:apigateway:eu-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:eu-west-2:${local.aws_account_id}:function:${substr("${local.prefix}--api--producer--status", 0, 64)}/invocations"
3741
}
38-
42+
endpoint_allowed_methods = {
43+
"/DocumentReference" = "GET,POST",
44+
"/DocumentReference/{id}" = "GET,PUT,DELETE"
45+
}
3946
kms_key_id = module.kms__cloudwatch.kms_arn
4047
domain = local.apis.domain
4148
path = local.apis.producer.path

terraform/infrastructure/consumer.tftpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
{
6464
"type": "DocumentReference",
6565
"profile": "http://hl7.org/fhir/R4/documentreference.html",
66-
"documentation": "Additional business rules apply to constrain patient, organisation and type/category content.",
66+
"documentation": "Additional business rules apply to constrain patient, organisation and type/category content. Note that HEAD requests are not supported.",
6767
"interaction": [
6868
{
6969
"code": "read",

terraform/infrastructure/modules/api_gateway/api_gateway.tf

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,20 @@ resource "aws_api_gateway_deployment" "api_gateway_deployment" {
5050
rest_api_id = aws_api_gateway_rest_api.api_gateway_rest_api.id
5151

5252
triggers = {
53-
redeployment = sha1(jsonencode(aws_api_gateway_rest_api.api_gateway_rest_api.body))
54-
resource_change = "${md5(file("${path.module}/api_gateway.tf"))}"
55-
capabilities = sha1(var.capability_statement_content)
53+
redeployment = sha1(jsonencode(aws_api_gateway_rest_api.api_gateway_rest_api.body))
54+
resource_change = "${md5(file("${path.module}/api_gateway.tf"))}"
55+
capabilities = sha1(var.capability_statement_content)
56+
head_responses_change = md5(file("${path.module}/head_responses.tf"))
57+
parent_api_gateway_change = md5(file("${path.module}/../../api_gateway.tf"))
5658
}
5759

5860
lifecycle {
5961
create_before_destroy = true
6062
}
6163

6264
depends_on = [
63-
aws_api_gateway_rest_api.api_gateway_rest_api
65+
aws_api_gateway_rest_api.api_gateway_rest_api,
66+
aws_api_gateway_integration_response.head_integration_response
6467
]
6568
}
6669

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Define a reusable map of allowed methods for each path
2+
data "aws_api_gateway_resource" "resource" {
3+
for_each = var.endpoint_allowed_methods
4+
rest_api_id = aws_api_gateway_rest_api.api_gateway_rest_api.id
5+
path = each.key
6+
7+
depends_on = [aws_api_gateway_rest_api.api_gateway_rest_api]
8+
}
9+
10+
# Add HEAD method to each resource with 405 response
11+
resource "aws_api_gateway_method" "head_method" {
12+
for_each = var.endpoint_allowed_methods
13+
14+
rest_api_id = aws_api_gateway_rest_api.api_gateway_rest_api.id
15+
resource_id = data.aws_api_gateway_resource.resource[each.key].id
16+
http_method = "HEAD"
17+
authorization = "NONE"
18+
}
19+
20+
resource "aws_api_gateway_integration" "head_integration" {
21+
for_each = var.endpoint_allowed_methods
22+
23+
rest_api_id = aws_api_gateway_rest_api.api_gateway_rest_api.id
24+
resource_id = data.aws_api_gateway_resource.resource[each.key].id
25+
http_method = aws_api_gateway_method.head_method[each.key].http_method
26+
type = "MOCK"
27+
passthrough_behavior = "WHEN_NO_TEMPLATES"
28+
29+
request_templates = {
30+
"application/json" = <<-EOF
31+
{ "statusCode": 405 }
32+
EOF
33+
"application/json+fhir" = <<-EOF
34+
{ "statusCode": 405 }
35+
EOF
36+
"application/fhir+json" = <<-EOF
37+
{ "statusCode": 405 }
38+
EOF
39+
}
40+
}
41+
42+
resource "aws_api_gateway_method_response" "head_method_response" {
43+
for_each = var.endpoint_allowed_methods
44+
45+
rest_api_id = aws_api_gateway_rest_api.api_gateway_rest_api.id
46+
resource_id = data.aws_api_gateway_resource.resource[each.key].id
47+
http_method = aws_api_gateway_method.head_method[each.key].http_method
48+
status_code = "405"
49+
50+
response_parameters = {
51+
"method.response.header.Allow" = true
52+
}
53+
}
54+
55+
resource "aws_api_gateway_integration_response" "head_integration_response" {
56+
for_each = var.endpoint_allowed_methods
57+
58+
rest_api_id = aws_api_gateway_rest_api.api_gateway_rest_api.id
59+
resource_id = data.aws_api_gateway_resource.resource[each.key].id
60+
http_method = aws_api_gateway_method.head_method[each.key].http_method
61+
status_code = aws_api_gateway_method_response.head_method_response[each.key].status_code
62+
selection_pattern = "" # default catch-all
63+
64+
response_parameters = {
65+
"method.response.header.Allow" = "'${each.value}'"
66+
}
67+
}

terraform/infrastructure/modules/api_gateway/vars.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,7 @@ variable "retention" {
2222
default = 90
2323
type = number
2424
}
25+
26+
variable "endpoint_allowed_methods" {
27+
type = map(string)
28+
}

0 commit comments

Comments
 (0)