Skip to content

Commit

Permalink
Merge pull request #381 from NHSDigital/release/2024-10-29
Browse files Browse the repository at this point in the history
Release/2024-10-29
  • Loading branch information
megan-bower4 authored Oct 31, 2024
2 parents a4109c4 + f71d69b commit 88f8423
Show file tree
Hide file tree
Showing 58 changed files with 1,823 additions and 160 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 2024-10-29
- [PI-565] Add EPR questionnaires
- [PI-577] Create Message Set Device Reference Data
- [PI-574] CPM Smoke tests don't write data to DB

## 2024-10-25
- [PI-551] Remove FHIR from Read CPM Product flow
- [PI-553] Remove FHIR from Delete CPM Product flow
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2024.10.25
2024.10.29
3 changes: 3 additions & 0 deletions changelog/2024-10-29.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- [PI-565] Add EPR questionnaires
- [PI-577] Create Message Set Device Reference Data
- [PI-574] CPM Smoke tests don't write data to DB
43 changes: 43 additions & 0 deletions infrastructure/swagger/05_paths.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,49 @@ paths:
- ${authoriser_name}: []
- app-level0: []

? /ProductTeam/{product_team_id}/Product/{product_id}/DeviceReferenceData/MhsMessageSet
: post:
operationId: createDeviceReferenceDataMessageSet
summary: createDeviceReferenceDataMessageSet endpoint for APIGEE integration
parameters:
- name: product_team_id
in: path
required: true
description: logical identifier
schema:
type: string
- name: product_id
in: path
required: true
description: logical identifier
schema:
type: string
- *RequestHeaderVersion
- *RequestHeaderRequestId
- *RequestHeaderCorrelationId
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
questionnaire_responses:
type: object
description: Questionnaire Responses for MHS Message Set questionnaire
responses:
responses:
"201":
<<: *Response201
"4XX":
<<: *Response4XX
x-amazon-apigateway-integration:
<<: *ApiGatewayIntegration
uri: ${method_createDeviceReferenceDataMessageSet}
security:
- ${authoriser_name}: []
- app-level0: []

? /ProductTeam/{product_team_id}/Product/{product_id}/DeviceReferenceData/{device_reference_data_id}
: get:
operationId: readDeviceReferenceData
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "connecting-party-manager"
version = "2024.10.25"
version = "2024.10.29"
description = "Repository for the Connecting Party Manager API and related services"
authors = ["NHS England"]
license = "LICENSE.md"
Expand All @@ -27,6 +27,7 @@ urllib3 = "<3"
orjson = "^3.9.15"
attrs = "^24.2.0"
locust = "^2.29.1"
jsonschema = "^4.23.0"

[tool.poetry.group.dev.dependencies]
pre-commit = "^4.0.0"
Expand Down
26 changes: 26 additions & 0 deletions src/api/createDeviceReferenceDataMessageSet/index.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from api_utils.api_step_chain import execute_step_chain
from event.aws.client import dynamodb_client
from event.environment import BaseEnvironment
from event.logging.logger import setup_logger

from .src.v1.steps import steps as v1_steps


class Environment(BaseEnvironment):
DYNAMODB_TABLE: str


versioned_steps = {"1": v1_steps}
cache = {
**Environment.build().dict(),
"DYNAMODB_CLIENT": dynamodb_client(),
}


def handler(event: dict, context=None):
setup_logger(service_name=__file__)
return execute_step_chain(
event=event,
cache=cache,
versioned_steps=versioned_steps,
)
4 changes: 4 additions & 0 deletions src/api/createDeviceReferenceDataMessageSet/make/make.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from builder.lambda_build import build

if __name__ == "__main__":
build(__file__)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[
"dynamodb:Query",
"dynamodb:PutItem",
"dynamodb:GetItem",
"dynamodb:UpdateItem"
]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
["kms:Decrypt"]
130 changes: 130 additions & 0 deletions src/api/createDeviceReferenceDataMessageSet/src/v1/steps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
from http import HTTPStatus

from domain.api.common_steps.general import parse_event_body
from domain.api.common_steps.read_product import (
parse_path_params,
read_product,
read_product_team,
)
from domain.core.cpm_product.v1 import CpmProduct
from domain.core.device_reference_data.v1 import DeviceReferenceData
from domain.core.error import ConfigurationError
from domain.core.product_key.v1 import ProductKeyType
from domain.core.questionnaire.v3 import Questionnaire, QuestionnaireResponse
from domain.repository.device_reference_data_repository.v1 import (
DeviceReferenceDataRepository,
)
from domain.repository.errors import AlreadyExistsError
from domain.repository.questionnaire_repository.v2 import QuestionnaireRepository
from domain.repository.questionnaire_repository.v2.questionnaires import (
QuestionnaireInstance,
)
from domain.request_models.v1 import CreateDeviceReferenceMessageSetsDataParams
from domain.response.validation_errors import mark_validation_errors_as_inbound


@mark_validation_errors_as_inbound
def parse_device_reference_data_for_epr_payload(
data, cache
) -> CreateDeviceReferenceMessageSetsDataParams:
payload: dict = data[parse_event_body]
return CreateDeviceReferenceMessageSetsDataParams(**payload)


def get_party_key(data, cache) -> str:
product: CpmProduct = data[read_product]
party_keys = [
key.key_value
for key in product.keys
if key.key_type is ProductKeyType.PARTY_KEY
]
try:
(party_key,) = party_keys
except ValueError:
raise ConfigurationError(
"Cannot create Message Set in Product without exactly one Party Key"
)
return party_key


def require_no_existing_message_sets_device_reference_data(
data, cache
) -> list[QuestionnaireResponse]:
product: CpmProduct = data[read_product]
repo = DeviceReferenceDataRepository(
table_name=cache["DYNAMODB_TABLE"], dynamodb_client=cache["DYNAMODB_CLIENT"]
)
results = repo.search(
product_team_id=product.product_team_id, product_id=product.id
)
if len(results) > 0:
raise AlreadyExistsError(
"This product already has a 'Message Set' DeviceReferenceData. "
"Please update, or delete and recreate if you wish to make changes."
)


def read_questionnaire(data, cache) -> Questionnaire:
return QuestionnaireRepository().read(QuestionnaireInstance.SPINE_MHS_MESSAGE_SETS)


def validate_questionnaire_responses(data, cache) -> list[QuestionnaireResponse]:
questionnaire: Questionnaire = data[read_questionnaire]
payload: CreateDeviceReferenceMessageSetsDataParams = data[
parse_device_reference_data_for_epr_payload
]
raw_questionnaire_responses = payload.questionnaire_responses[
QuestionnaireInstance.SPINE_MHS_MESSAGE_SETS
]
return [questionnaire.validate(data=qr) for qr in raw_questionnaire_responses]


def create_message_set_device_reference_data(data, cache) -> DeviceReferenceData:
product: CpmProduct = data[read_product]
party_key: str = data[get_party_key]
return product.create_device_reference_data(name=f"{party_key} - MHS Message Set")


def add_questionnaire_response(data, cache) -> list[QuestionnaireResponse]:
questionnaire_responses: list[QuestionnaireResponse] = data[
validate_questionnaire_responses
]
device_reference_data: DeviceReferenceData = data[
create_message_set_device_reference_data
]
for qr in questionnaire_responses:
device_reference_data.add_questionnaire_response(qr)


def write_device_reference_data(data: dict[str, CpmProduct], cache) -> CpmProduct:
device_reference_data: DeviceReferenceData = data[
create_message_set_device_reference_data
]
repo = DeviceReferenceDataRepository(
table_name=cache["DYNAMODB_TABLE"], dynamodb_client=cache["DYNAMODB_CLIENT"]
)
return repo.write(device_reference_data)


def set_http_status(data, cache) -> tuple[HTTPStatus, str]:
device_reference_data: DeviceReferenceData = data[
create_message_set_device_reference_data
]
return HTTPStatus.CREATED, device_reference_data.state()


steps = [
parse_event_body,
parse_path_params,
parse_device_reference_data_for_epr_payload,
read_product_team,
read_product,
get_party_key,
require_no_existing_message_sets_device_reference_data,
read_questionnaire,
validate_questionnaire_responses,
create_message_set_device_reference_data,
add_questionnaire_response,
write_device_reference_data,
set_http_status,
]
Loading

0 comments on commit 88f8423

Please sign in to comment.