Skip to content

Commit

Permalink
[feature/PI-605-bulk_etl_transform] epr bulk create
Browse files Browse the repository at this point in the history
  • Loading branch information
jaklinger committed Nov 20, 2024
1 parent a1413a6 commit e5a9818
Show file tree
Hide file tree
Showing 36 changed files with 2,282 additions and 166 deletions.
37 changes: 21 additions & 16 deletions src/api/createDeviceMessageHandlingSystem/src/v1/steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
)
from domain.core.cpm_product import CpmProduct
from domain.core.device import (
MHS_DEVICE_NAME,
Device,
DeviceKeyAddedEvent,
DeviceReferenceDataIdAddedEvent,
Expand All @@ -31,6 +30,7 @@
)
from domain.request_models import CpmProductPathParams, CreateMhsDeviceIncomingParams
from domain.response.validation_errors import mark_validation_errors_as_inbound
from sds.epr.constants import EprNameTemplate, SdsDeviceReferenceDataPath, SdsFieldName


@mark_validation_errors_as_inbound
Expand All @@ -42,13 +42,17 @@ def parse_mhs_device_payload(data, cache) -> CreateMhsDeviceIncomingParams:
def check_for_existing_mhs(data, cache):
product_team: ProductTeam = data[read_product_team]
product: CpmProduct = data[read_product]
party_key: str = data[get_party_key]

device_repo = DeviceRepository(
table_name=cache["DYNAMODB_TABLE"], dynamodb_client=cache["DYNAMODB_CLIENT"]
)

devices = device_repo.search(product_team_id=product_team.id, product_id=product.id)
if any(device.name == MHS_DEVICE_NAME for device in devices):
if any(
device.name == EprNameTemplate.MHS_DEVICE.format(party_key=party_key)
for device in devices
):
raise ConfigurationError(
"There is already an existing MHS Device for this Product"
)
Expand All @@ -65,12 +69,11 @@ def read_device_reference_data(data, cache) -> DeviceReferenceData:
)

party_key: str = data[get_party_key]
# use {QuestionnaireInstance.SPINE_MHS_MESSAGE_SETS}
mhs_message_set_drd_name = f"{party_key} - MHS Message Set"

try:
(device_reference_data,) = filter(
lambda drd: drd.name == mhs_message_set_drd_name, device_reference_datas
lambda drd: drd.name
== EprNameTemplate.MESSAGE_SETS.format(party_key=party_key),
device_reference_datas,
)
except ValueError:
raise ConfigurationError(
Expand Down Expand Up @@ -98,11 +101,14 @@ def validate_spine_mhs_questionnaire_response(data, cache) -> QuestionnaireRespo

def create_mhs_device(data, cache) -> Device:
product: CpmProduct = data[read_product]
party_key: str = data[get_party_key]
payload: CreateMhsDeviceIncomingParams = data[parse_mhs_device_payload]

# Create a new Device dictionary excluding 'questionnaire_responses'
device_payload = payload.dict(exclude={"questionnaire_responses"})
return product.create_device(**device_payload)
return product.create_device(
name=EprNameTemplate.MHS_DEVICE.format(party_key=party_key), **device_payload
)


def create_party_key_tag(data, cache) -> DeviceTagAddedEvent:
Expand All @@ -114,20 +120,18 @@ def create_cpa_id_keys(data, cache) -> DeviceKeyAddedEvent:
mhs_device: Device = data[create_mhs_device]
party_key = data[get_party_key]
drd: DeviceReferenceData = data[read_device_reference_data]
interaction_ids = []

# Extract Interaction IDs from questionnaire responses
questionnaire_responses = drd.questionnaire_responses.get(
f"{QuestionnaireInstance.SPINE_MHS_MESSAGE_SETS}/1", []
)
for response in questionnaire_responses:
interaction_ids.append(response.data.get("Interaction ID"))

# Use cpa_id in furture
interaction_ids = [
response.data.get(SdsFieldName.INTERACTION_ID)
for response in questionnaire_responses
]

for id in interaction_ids:
mhs_device.add_key(
key_type=DeviceKeyType.INTERACTION_ID, key_value=f"{party_key}:{id}"
)
mhs_device.add_key(key_type=DeviceKeyType.CPA_ID, key_value=f"{party_key}:{id}")

return mhs_device

Expand All @@ -136,7 +140,8 @@ def add_device_reference_data_id(data, cache) -> DeviceReferenceDataIdAddedEvent
mhs_device: Device = data[create_mhs_device]
drd: DeviceReferenceData = data[read_device_reference_data]
return mhs_device.add_device_reference_data_id(
device_reference_data_id=str(drd.id), path_to_data=["*"]
device_reference_data_id=str(drd.id),
path_to_data=[SdsDeviceReferenceDataPath.ALL],
)


Expand Down
10 changes: 6 additions & 4 deletions src/api/createDeviceMessageHandlingSystem/tests/test_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@
QuestionnaireRepository,
)
from event.json import json_loads
from sds.epr.constants import MHS_DEVICE_SUFFIX, EprNameTemplate

from test_helpers.dynamodb import mock_table
from test_helpers.uuid import consistent_uuid

TABLE_NAME = "hiya"
DEVICE_NAME = "Product-MHS"
DEVICE_NAME = "ABC1234-987654 - Message Handling System"
ODS_CODE = "AAA"
PRODUCT_ID = ProductId.create()
PRODUCT_TEAM_NAME = "My Product Team"
Expand All @@ -52,6 +53,7 @@
"MHS Is Authenticated": "PERSISTENT",
"Product Key": "product-key-001",
"Requestor URP": "requestor-789",
"MHS Manufacturer Organisation": "AAA",
}


Expand Down Expand Up @@ -103,7 +105,7 @@ def mock_epr_product_with_message_set_drd() -> (

# Set up DeviceReferenceData in DB
device_reference_data = product.create_device_reference_data(
name="ABC1234-987654 - MHS Message Set"
name=EprNameTemplate.MESSAGE_SETS.format(party_key="ABC1234-987654")
)
device_reference_data.add_questionnaire_response(questionnaire_response)
device_reference_data.add_questionnaire_response(questionnaire_response_2)
Expand Down Expand Up @@ -205,7 +207,7 @@ def test_index() -> None:
device = Device(**_device)
assert device.product_team_id == product.product_team_id
assert device.product_id == product.id
assert device.name == DEVICE_NAME
assert device.name.endswith(MHS_DEVICE_SUFFIX)
assert device.ods_code == ODS_CODE
assert device.created_on.date() == datetime.today().date()
assert device.updated_on.date() == datetime.today().date()
Expand Down Expand Up @@ -302,7 +304,7 @@ def test_incoming_errors(body, path_parameters, error_code, status_code):
}
},
"MISSING_VALUE",
"Failed to validate data against 'spine_mhs/1': 'Unique Identifier' is a required property",
"Failed to validate data against 'spine_mhs/1': 'MHS Manufacturer Organisation' is a required property",
400,
),
],
Expand Down
7 changes: 3 additions & 4 deletions src/api/createDeviceReferenceDataASActions/src/v1/steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@
)
from domain.request_models import CreateDeviceReferenceAdditionalInteractionsDataParams
from domain.response.validation_errors import mark_validation_errors_as_inbound

DEVICE_NAME_MARKER = "AS Additional Interactions"
from sds.epr.constants import ADDITIONAL_INTERACTIONS_SUFFIX, EprNameTemplate


@mark_validation_errors_as_inbound
Expand Down Expand Up @@ -60,7 +59,7 @@ def require_no_existing_additional_interactions_device_reference_data(
product_team_id=product.product_team_id, product_id=product.id
)
if any(
device_reference_data.name.endswith(DEVICE_NAME_MARKER)
device_reference_data.name.endswith(ADDITIONAL_INTERACTIONS_SUFFIX)
for device_reference_data in results
):
raise AlreadyExistsError(
Expand Down Expand Up @@ -91,7 +90,7 @@ def create_additional_interactions_device_reference_data(
product: CpmProduct = data[read_product]
party_key: str = data[get_party_key]
return product.create_device_reference_data(
name=f"{party_key} - {DEVICE_NAME_MARKER}"
name=EprNameTemplate.ADDITIONAL_INTERACTIONS.format(party_key=party_key)
)


Expand Down
9 changes: 4 additions & 5 deletions src/api/createDeviceReferenceDataMessageSet/src/v1/steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@
)
from domain.request_models import CreateDeviceReferenceMessageSetsDataParams
from domain.response.validation_errors import mark_validation_errors_as_inbound

DEVICE_NAME_MARKER = "MHS Message Set"
from sds.epr.constants import MESSAGE_SETS_SUFFIX, EprNameTemplate


@mark_validation_errors_as_inbound
Expand All @@ -43,11 +42,11 @@ def require_no_existing_message_sets_device_reference_data(
product_team_id=product.product_team_id, product_id=product.id
)
if any(
device_reference_data.name.endswith(DEVICE_NAME_MARKER)
device_reference_data.name.endswith(MESSAGE_SETS_SUFFIX)
for device_reference_data in results
):
raise AlreadyExistsError(
"This product already has a 'Message Set' DeviceReferenceData. "
"This product already has a 'Message Sets' DeviceReferenceData. "
"Please update, or delete and recreate if you wish to make changes."
)

Expand All @@ -71,7 +70,7 @@ 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} - {DEVICE_NAME_MARKER}"
name=EprNameTemplate.MESSAGE_SETS.format(party_key=party_key)
)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def test_index_without_questionnaire() -> None:
device_reference_data = DeviceReferenceData(**_device_reference_data)
assert device_reference_data.product_id == product.id
assert device_reference_data.product_team_id == product.product_team_id
assert device_reference_data.name == "AAA-100001 - MHS Message Set"
assert device_reference_data.name == "AAA-100001 - MHS Message Sets"
assert device_reference_data.ods_code == ODS_CODE
assert device_reference_data.created_on.date() == datetime.today().date()
assert device_reference_data.updated_on is None
Expand Down Expand Up @@ -136,7 +136,7 @@ def test_index_with_questionnaire() -> None:
device_reference_data = DeviceReferenceData(**_device_reference_data)
assert device_reference_data.product_id == product.id
assert device_reference_data.product_team_id == product.product_team_id
assert device_reference_data.name == "AAA-100001 - MHS Message Set"
assert device_reference_data.name == "AAA-100001 - MHS Message Sets"
assert device_reference_data.ods_code == ODS_CODE
assert device_reference_data.created_on.date() == datetime.today().date()
assert device_reference_data.updated_on.date() == datetime.today().date()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,13 +237,13 @@ Feature: Create MHS Device - failure scenarios
| questionnaire_responses.spine_mhs.0.Address | http://example.com |
| questionnaire_responses.spine_mhs.0.Unique Identifier | 123456 |
Then I receive a status code "400" with body
| path | value |
| errors.0.code | MISSING_VALUE |
| errors.0.message | Failed to validate data against 'spine_mhs/1': 'Managing Organization' is a required property |
| path | value |
| errors.0.code | MISSING_VALUE |
| errors.0.message | Failed to validate data against 'spine_mhs/1': 'MHS Manufacturer Organisation' is a required property |
And the response headers contain:
| name | value |
| Content-Type | application/json |
| Content-Length | 147 |
| Content-Length | 155 |

Scenario: Cannot create a MHS Device with a Product that already has an MHS Device
Given I have already made a "POST" request with "default" headers to "ProductTeam" with body:
Expand All @@ -264,6 +264,7 @@ Feature: Create MHS Device - failure scenarios
| questionnaire_responses.spine_mhs.0.Address | http://example.com |
| questionnaire_responses.spine_mhs.0.Unique Identifier | 123456 |
| questionnaire_responses.spine_mhs.0.Managing Organization | Example Org |
| questionnaire_responses.spine_mhs.0.MHS Manufacturer Organisation | AAA |
| questionnaire_responses.spine_mhs.0.MHS Party key | party-key-001 |
| questionnaire_responses.spine_mhs.0.MHS CPA ID | cpa-id-001 |
| questionnaire_responses.spine_mhs.0.Approver URP | approver-123 |
Expand All @@ -283,6 +284,7 @@ Feature: Create MHS Device - failure scenarios
| questionnaire_responses.spine_mhs.0.Address | http://example.com |
| questionnaire_responses.spine_mhs.0.Unique Identifier | 123457 |
| questionnaire_responses.spine_mhs.0.Managing Organization | Example Org |
| questionnaire_responses.spine_mhs.0.MHS Manufacturer Organisation | AAA |
| questionnaire_responses.spine_mhs.0.MHS Party key | party-key-003 |
| questionnaire_responses.spine_mhs.0.MHS CPA ID | cpa-id-001 |
| questionnaire_responses.spine_mhs.0.Approver URP | approver-123 |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Feature: Create MHS Device - success scenarios
| questionnaire_responses.spine_mhs.0.Address | http://example.com |
| questionnaire_responses.spine_mhs.0.Unique Identifier | 123456 |
| questionnaire_responses.spine_mhs.0.Managing Organization | Example Org |
| questionnaire_responses.spine_mhs.0.MHS Manufacturer Organisation | AAA |
| questionnaire_responses.spine_mhs.0.MHS Party key | party-key-001 |
| questionnaire_responses.spine_mhs.0.MHS CPA ID | cpa-id-001 |
| questionnaire_responses.spine_mhs.0.Approver URP | approver-123 |
Expand All @@ -48,36 +49,36 @@ Feature: Create MHS Device - success scenarios
Then I receive a status code "201" with body
| path | value |
| id | << ignore >> |
| name | Product-MHS |
| name | F5H1R-850000 - Message Handling System |
| status | active |
| product_id | ${ note(product_id) } |
| product_team_id | ${ note(product_team_id) } |
| ods_code | F5H1R |
| created_on | << ignore >> |
| updated_on | << ignore >> |
| deleted_on | << ignore >> |
| keys.0.key_type | interaction_id |
| keys.0.key_type | cpa_id |
| keys.0.key_value | F5H1R-850000:urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V001 |
| questionnaire_responses | << ignore >> |
| device_reference_data | << ignore >> |
And the response headers contain:
| name | value |
| Content-Type | application/json |
| Content-Length | 1295 |
| Content-Length | 1354 |
And I note the response field "$.id" as "device_id"
When I make a "GET" request with "default" headers to "ProductTeam/${ note(product_team_id) }/Product/${ note(product_id) }/Device/${ note(device_id) }"
Then I receive a status code "200" with body
| path | value |
| id | ${ note(device_id) } |
| name | Product-MHS |
| name | F5H1R-850000 - Message Handling System |
| status | active |
| product_id | ${ note(product_id) } |
| product_team_id | ${ note(product_team_id) } |
| ods_code | F5H1R |
| created_on | << ignore >> |
| updated_on | << ignore >> |
| deleted_on | << ignore >> |
| keys.0.key_type | interaction_id |
| keys.0.key_type | cpa_id |
| keys.0.key_value | F5H1R-850000:urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V001 |
| tags.0.0.0 | ${ note(party_key_tag) } |
| tags.0.0.1 | ${ note(party_key_value) } |
Expand All @@ -86,7 +87,7 @@ Feature: Create MHS Device - success scenarios
And the response headers contain:
| name | value |
| Content-Type | application/json |
| Content-Length | 1338 |
| Content-Length | 1397 |

Examples:
| product_team_id | product_id |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,13 @@ Feature: Create "Message Set" Device Reference Data - failure scenarios
And I have already made a "POST" request with "default" headers to "ProductTeam/${ note(product_team_id) }/Product/${ note(product_id) }/DeviceReferenceData/MhsMessageSet"
When I make a "POST" request with "default" headers to "ProductTeam/${ note(product_team_id) }/Product/${ note(product_id) }/DeviceReferenceData/MhsMessageSet"
Then I receive a status code "400" with body
| path | value |
| errors.0.code | VALIDATION_ERROR |
| errors.0.message | This product already has a 'Message Set' DeviceReferenceData. Please update, or delete and recreate if you wish to make changes. |
| path | value |
| errors.0.code | VALIDATION_ERROR |
| errors.0.message | This product already has a 'Message Sets' DeviceReferenceData. Please update, or delete and recreate if you wish to make changes. |
And the response headers contain:
| name | value |
| Content-Type | application/json |
| Content-Length | 185 |
| Content-Length | 186 |

Scenario: Fail to create an "MHS Message Set" Device Reference Data in non-EPR product
Given I have already made a "POST" request with "default" headers to "ProductTeam" with body:
Expand Down
Loading

0 comments on commit e5a9818

Please sign in to comment.