Skip to content

Commit 88f8423

Browse files
authored
Merge pull request #381 from NHSDigital/release/2024-10-29
Release/2024-10-29
2 parents a4109c4 + f71d69b commit 88f8423

File tree

58 files changed

+1823
-160
lines changed

Some content is hidden

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

58 files changed

+1823
-160
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## 2024-10-29
4+
- [PI-565] Add EPR questionnaires
5+
- [PI-577] Create Message Set Device Reference Data
6+
- [PI-574] CPM Smoke tests don't write data to DB
7+
38
## 2024-10-25
49
- [PI-551] Remove FHIR from Read CPM Product flow
510
- [PI-553] Remove FHIR from Delete CPM Product flow

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2024.10.25
1+
2024.10.29

changelog/2024-10-29.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
- [PI-565] Add EPR questionnaires
2+
- [PI-577] Create Message Set Device Reference Data
3+
- [PI-574] CPM Smoke tests don't write data to DB

infrastructure/swagger/05_paths.yaml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,49 @@ paths:
339339
- ${authoriser_name}: []
340340
- app-level0: []
341341

342+
? /ProductTeam/{product_team_id}/Product/{product_id}/DeviceReferenceData/MhsMessageSet
343+
: post:
344+
operationId: createDeviceReferenceDataMessageSet
345+
summary: createDeviceReferenceDataMessageSet endpoint for APIGEE integration
346+
parameters:
347+
- name: product_team_id
348+
in: path
349+
required: true
350+
description: logical identifier
351+
schema:
352+
type: string
353+
- name: product_id
354+
in: path
355+
required: true
356+
description: logical identifier
357+
schema:
358+
type: string
359+
- *RequestHeaderVersion
360+
- *RequestHeaderRequestId
361+
- *RequestHeaderCorrelationId
362+
requestBody:
363+
required: true
364+
content:
365+
application/json:
366+
schema:
367+
type: object
368+
properties:
369+
questionnaire_responses:
370+
type: object
371+
description: Questionnaire Responses for MHS Message Set questionnaire
372+
responses:
373+
responses:
374+
"201":
375+
<<: *Response201
376+
"4XX":
377+
<<: *Response4XX
378+
x-amazon-apigateway-integration:
379+
<<: *ApiGatewayIntegration
380+
uri: ${method_createDeviceReferenceDataMessageSet}
381+
security:
382+
- ${authoriser_name}: []
383+
- app-level0: []
384+
342385
? /ProductTeam/{product_team_id}/Product/{product_id}/DeviceReferenceData/{device_reference_data_id}
343386
: get:
344387
operationId: readDeviceReferenceData

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "connecting-party-manager"
3-
version = "2024.10.25"
3+
version = "2024.10.29"
44
description = "Repository for the Connecting Party Manager API and related services"
55
authors = ["NHS England"]
66
license = "LICENSE.md"
@@ -27,6 +27,7 @@ urllib3 = "<3"
2727
orjson = "^3.9.15"
2828
attrs = "^24.2.0"
2929
locust = "^2.29.1"
30+
jsonschema = "^4.23.0"
3031

3132
[tool.poetry.group.dev.dependencies]
3233
pre-commit = "^4.0.0"
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from api_utils.api_step_chain import execute_step_chain
2+
from event.aws.client import dynamodb_client
3+
from event.environment import BaseEnvironment
4+
from event.logging.logger import setup_logger
5+
6+
from .src.v1.steps import steps as v1_steps
7+
8+
9+
class Environment(BaseEnvironment):
10+
DYNAMODB_TABLE: str
11+
12+
13+
versioned_steps = {"1": v1_steps}
14+
cache = {
15+
**Environment.build().dict(),
16+
"DYNAMODB_CLIENT": dynamodb_client(),
17+
}
18+
19+
20+
def handler(event: dict, context=None):
21+
setup_logger(service_name=__file__)
22+
return execute_step_chain(
23+
event=event,
24+
cache=cache,
25+
versioned_steps=versioned_steps,
26+
)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from builder.lambda_build import build
2+
3+
if __name__ == "__main__":
4+
build(__file__)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[
2+
"dynamodb:Query",
3+
"dynamodb:PutItem",
4+
"dynamodb:GetItem",
5+
"dynamodb:UpdateItem"
6+
]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
["kms:Decrypt"]
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
from http import HTTPStatus
2+
3+
from domain.api.common_steps.general import parse_event_body
4+
from domain.api.common_steps.read_product import (
5+
parse_path_params,
6+
read_product,
7+
read_product_team,
8+
)
9+
from domain.core.cpm_product.v1 import CpmProduct
10+
from domain.core.device_reference_data.v1 import DeviceReferenceData
11+
from domain.core.error import ConfigurationError
12+
from domain.core.product_key.v1 import ProductKeyType
13+
from domain.core.questionnaire.v3 import Questionnaire, QuestionnaireResponse
14+
from domain.repository.device_reference_data_repository.v1 import (
15+
DeviceReferenceDataRepository,
16+
)
17+
from domain.repository.errors import AlreadyExistsError
18+
from domain.repository.questionnaire_repository.v2 import QuestionnaireRepository
19+
from domain.repository.questionnaire_repository.v2.questionnaires import (
20+
QuestionnaireInstance,
21+
)
22+
from domain.request_models.v1 import CreateDeviceReferenceMessageSetsDataParams
23+
from domain.response.validation_errors import mark_validation_errors_as_inbound
24+
25+
26+
@mark_validation_errors_as_inbound
27+
def parse_device_reference_data_for_epr_payload(
28+
data, cache
29+
) -> CreateDeviceReferenceMessageSetsDataParams:
30+
payload: dict = data[parse_event_body]
31+
return CreateDeviceReferenceMessageSetsDataParams(**payload)
32+
33+
34+
def get_party_key(data, cache) -> str:
35+
product: CpmProduct = data[read_product]
36+
party_keys = [
37+
key.key_value
38+
for key in product.keys
39+
if key.key_type is ProductKeyType.PARTY_KEY
40+
]
41+
try:
42+
(party_key,) = party_keys
43+
except ValueError:
44+
raise ConfigurationError(
45+
"Cannot create Message Set in Product without exactly one Party Key"
46+
)
47+
return party_key
48+
49+
50+
def require_no_existing_message_sets_device_reference_data(
51+
data, cache
52+
) -> list[QuestionnaireResponse]:
53+
product: CpmProduct = data[read_product]
54+
repo = DeviceReferenceDataRepository(
55+
table_name=cache["DYNAMODB_TABLE"], dynamodb_client=cache["DYNAMODB_CLIENT"]
56+
)
57+
results = repo.search(
58+
product_team_id=product.product_team_id, product_id=product.id
59+
)
60+
if len(results) > 0:
61+
raise AlreadyExistsError(
62+
"This product already has a 'Message Set' DeviceReferenceData. "
63+
"Please update, or delete and recreate if you wish to make changes."
64+
)
65+
66+
67+
def read_questionnaire(data, cache) -> Questionnaire:
68+
return QuestionnaireRepository().read(QuestionnaireInstance.SPINE_MHS_MESSAGE_SETS)
69+
70+
71+
def validate_questionnaire_responses(data, cache) -> list[QuestionnaireResponse]:
72+
questionnaire: Questionnaire = data[read_questionnaire]
73+
payload: CreateDeviceReferenceMessageSetsDataParams = data[
74+
parse_device_reference_data_for_epr_payload
75+
]
76+
raw_questionnaire_responses = payload.questionnaire_responses[
77+
QuestionnaireInstance.SPINE_MHS_MESSAGE_SETS
78+
]
79+
return [questionnaire.validate(data=qr) for qr in raw_questionnaire_responses]
80+
81+
82+
def create_message_set_device_reference_data(data, cache) -> DeviceReferenceData:
83+
product: CpmProduct = data[read_product]
84+
party_key: str = data[get_party_key]
85+
return product.create_device_reference_data(name=f"{party_key} - MHS Message Set")
86+
87+
88+
def add_questionnaire_response(data, cache) -> list[QuestionnaireResponse]:
89+
questionnaire_responses: list[QuestionnaireResponse] = data[
90+
validate_questionnaire_responses
91+
]
92+
device_reference_data: DeviceReferenceData = data[
93+
create_message_set_device_reference_data
94+
]
95+
for qr in questionnaire_responses:
96+
device_reference_data.add_questionnaire_response(qr)
97+
98+
99+
def write_device_reference_data(data: dict[str, CpmProduct], cache) -> CpmProduct:
100+
device_reference_data: DeviceReferenceData = data[
101+
create_message_set_device_reference_data
102+
]
103+
repo = DeviceReferenceDataRepository(
104+
table_name=cache["DYNAMODB_TABLE"], dynamodb_client=cache["DYNAMODB_CLIENT"]
105+
)
106+
return repo.write(device_reference_data)
107+
108+
109+
def set_http_status(data, cache) -> tuple[HTTPStatus, str]:
110+
device_reference_data: DeviceReferenceData = data[
111+
create_message_set_device_reference_data
112+
]
113+
return HTTPStatus.CREATED, device_reference_data.state()
114+
115+
116+
steps = [
117+
parse_event_body,
118+
parse_path_params,
119+
parse_device_reference_data_for_epr_payload,
120+
read_product_team,
121+
read_product,
122+
get_party_key,
123+
require_no_existing_message_sets_device_reference_data,
124+
read_questionnaire,
125+
validate_questionnaire_responses,
126+
create_message_set_device_reference_data,
127+
add_questionnaire_response,
128+
write_device_reference_data,
129+
set_http_status,
130+
]

0 commit comments

Comments
 (0)