From 40bbe261c8afe4bac58de038680a1f79d8e73523 Mon Sep 17 00:00:00 2001 From: halprin <halprin@users.noreply.github.com> Date: Wed, 8 May 2024 10:00:38 -0600 Subject: [PATCH 1/5] DELETE ALL THE DEMOGRAPHICS --- .../trustedintermediary/e2e/HttpClient.java | 4 - .../e2e/DemographicsTest.groovy | 73 ----------- .../etor/EtorDomainRegistration.java | 37 +----- .../ConvertAndSendDemographicsUsecase.java | 32 ----- .../etor/demographics/Demographics.java | 14 -- .../PatientDemographicsController.java | 34 ----- .../PatientDemographicsResponse.java | 34 ----- .../etor/orders/OrderConverter.java | 4 - .../external/hapi/HapiDemographics.java | 15 --- .../external/hapi/HapiOrderConverter.java | 119 +---------------- etor/src/main/resources/openapi_etor.yaml | 40 ------ .../DemographicsMock.groovy | 35 ----- .../etor/EtorDomainRegistrationTest.groovy | 100 +-------------- ...nvertAndSendDemographicsUsecaseTest.groovy | 38 ------ .../PatientDemographicsControllerTest.groovy | 49 ------- .../PatientDemographicsResponseTest.groovy | 44 ------- .../external/hapi/HapiDemographicsTest.groovy | 61 --------- .../hapi/HapiOrderConverterTest.groovy | 120 +----------------- 18 files changed, 7 insertions(+), 846 deletions(-) delete mode 100644 e2e/src/test/groovy/gov/hhs/cdc/trustedintermediary/e2e/DemographicsTest.groovy delete mode 100644 etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/demographics/ConvertAndSendDemographicsUsecase.java delete mode 100644 etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/demographics/Demographics.java delete mode 100644 etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/demographics/PatientDemographicsController.java delete mode 100644 etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/demographics/PatientDemographicsResponse.java delete mode 100644 etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/hapi/HapiDemographics.java delete mode 100644 etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/DemographicsMock.groovy delete mode 100644 etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/demographics/ConvertAndSendDemographicsUsecaseTest.groovy delete mode 100644 etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/demographics/PatientDemographicsControllerTest.groovy delete mode 100644 etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/demographics/PatientDemographicsResponseTest.groovy delete mode 100644 etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/hapi/HapiDemographicsTest.groovy diff --git a/e2e/src/main/java/gov/hhs/cdc/trustedintermediary/e2e/HttpClient.java b/e2e/src/main/java/gov/hhs/cdc/trustedintermediary/e2e/HttpClient.java index 47c82c2ee..4478445ef 100644 --- a/e2e/src/main/java/gov/hhs/cdc/trustedintermediary/e2e/HttpClient.java +++ b/e2e/src/main/java/gov/hhs/cdc/trustedintermediary/e2e/HttpClient.java @@ -43,10 +43,6 @@ public static ClassicHttpResponse post( return handleResponseAndSetEntity(response); } - public static ClassicHttpResponse post(String path, String body) throws IOException { - return post(path, body, ContentType.APPLICATION_JSON, null); - } - private static ClassicHttpResponse handleResponseAndSetEntity(Response response) throws IOException { var responseHandler = new ResponseHandlerWithoutException(); diff --git a/e2e/src/test/groovy/gov/hhs/cdc/trustedintermediary/e2e/DemographicsTest.groovy b/e2e/src/test/groovy/gov/hhs/cdc/trustedintermediary/e2e/DemographicsTest.groovy deleted file mode 100644 index 389650e6d..000000000 --- a/e2e/src/test/groovy/gov/hhs/cdc/trustedintermediary/e2e/DemographicsTest.groovy +++ /dev/null @@ -1,73 +0,0 @@ -package gov.hhs.cdc.trustedintermediary.e2e - -import spock.lang.Specification - -import java.nio.file.Files -import java.nio.file.Path - -class DemographicsTest extends Specification { - - def demographicsClient = new EndpointClient("/v1/etor/demographics") - def newbornPatientJsonFileString = Files.readString(Path.of("../examples/Test/e2e/demographics/001_Patient_NBS.fhir")) - - def setup() { - SentPayloadReader.delete() - } - - def "a demographics response is returned from the ETOR demographics endpoint"() { - given: - def expectedFhirResourceId = "Bundle/bundle-with-patient" - def expectedPatientId = "MRN7465737865" - - when: - def response = demographicsClient.submit(newbornPatientJsonFileString, true) - def parsedJsonBody = JsonParser.parseContent(response) - - then: - response.getCode() == 200 - parsedJsonBody.fhirResourceId == expectedFhirResourceId - parsedJsonBody.patientId == expectedPatientId - } - - def "payload file check"() { - when: - def response = demographicsClient.submit(newbornPatientJsonFileString, true) - def parsedResponseBody = JsonParser.parseContent(response) - def sentPayload = SentPayloadReader.read() - def parsedSentPayload = JsonParser.parse(sentPayload) - - then: - response.getCode() == 200 - parsedSentPayload.entry[0].resource.resourceType == "MessageHeader" - parsedSentPayload.entry[2].resource.resourceType == "ServiceRequest" - - parsedSentPayload.entry[1].resource.resourceType == "Patient" - parsedSentPayload.entry[1].resource.id == "infant-twin-1" - - parsedSentPayload.entry[1].resource.identifier[1].value == parsedResponseBody.patientId //the second (index 1) identifier so happens to be the MRN - parsedSentPayload.resourceType + "/" + parsedSentPayload.id == parsedResponseBody.fhirResourceId - } - - def "return a 400 response when request has unexpected format"() { - given: - def invalidJsonRequest = newbornPatientJsonFileString.substring(1) - - when: - def response = demographicsClient.submit(invalidJsonRequest, true) - def parsedJsonBody = JsonParser.parseContent(response) - - then: - response.getCode() == 400 - !(parsedJsonBody.error as String).isEmpty() - } - - def "return a 401 response when making an unauthenticated request"() { - when: - def response = demographicsClient.submit(newbornPatientJsonFileString, false) - def parsedJsonBody = JsonParser.parseContent(response) - - then: - response.getCode() == 401 - !(parsedJsonBody.error as String).isEmpty() - } -} diff --git a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/EtorDomainRegistration.java b/etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/EtorDomainRegistration.java index bad7fbabc..f68a3b064 100644 --- a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/EtorDomainRegistration.java +++ b/etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/EtorDomainRegistration.java @@ -7,10 +7,6 @@ import gov.hhs.cdc.trustedintermediary.domainconnector.DomainResponseHelper; import gov.hhs.cdc.trustedintermediary.domainconnector.HttpEndpoint; import gov.hhs.cdc.trustedintermediary.domainconnector.UnableToReadOpenApiSpecificationException; -import gov.hhs.cdc.trustedintermediary.etor.demographics.ConvertAndSendDemographicsUsecase; -import gov.hhs.cdc.trustedintermediary.etor.demographics.Demographics; -import gov.hhs.cdc.trustedintermediary.etor.demographics.PatientDemographicsController; -import gov.hhs.cdc.trustedintermediary.etor.demographics.PatientDemographicsResponse; import gov.hhs.cdc.trustedintermediary.etor.messagelink.MessageLinkStorage; import gov.hhs.cdc.trustedintermediary.etor.messages.MessageRequestHandler; import gov.hhs.cdc.trustedintermediary.etor.messages.SendMessageHelper; @@ -65,20 +61,17 @@ /** * The domain connector for the ETOR domain. It connects it with the larger trusted intermediary. It - * houses the request processing logic for the demographics and orders endpoints. + * houses the request processing logic for the orders, results, and metadata endpoints. */ public class EtorDomainRegistration implements DomainConnector { - static final String DEMOGRAPHICS_API_ENDPOINT = "/v1/etor/demographics"; static final String ORDERS_API_ENDPOINT = "/v1/etor/orders"; static final String METADATA_API_ENDPOINT = "/v1/etor/metadata/{id}"; static final String RESULTS_API_ENDPOINT = "/v1/etor/results"; static final String CONSOLIDATED_SUMMARY_API_ENDPOINT = "/v1/etor/metadata/summary/{sender}"; - @Inject PatientDemographicsController patientDemographicsController; @Inject OrderController orderController; - @Inject ConvertAndSendDemographicsUsecase convertAndSendDemographicsUsecase; @Inject SendOrderUseCase sendOrderUseCase; @Inject ResultController resultController; @@ -94,8 +87,6 @@ public class EtorDomainRegistration implements DomainConnector { private final Map<HttpEndpoint, Function<DomainRequest, DomainResponse>> endpoints = Map.of( - new HttpEndpoint("POST", DEMOGRAPHICS_API_ENDPOINT, true), - this::handleDemographics, new HttpEndpoint("POST", ORDERS_API_ENDPOINT, true), this::handleOrders, new HttpEndpoint("GET", METADATA_API_ENDPOINT, true), this::handleMetadata, new HttpEndpoint("POST", RESULTS_API_ENDPOINT, true), this::handleResults, @@ -104,12 +95,6 @@ public class EtorDomainRegistration implements DomainConnector { @Override public Map<HttpEndpoint, Function<DomainRequest, DomainResponse>> domainRegistration() { - // Demographics - ApplicationContext.register( - PatientDemographicsController.class, PatientDemographicsController.getInstance()); - ApplicationContext.register( - ConvertAndSendDemographicsUsecase.class, - ConvertAndSendDemographicsUsecase.getInstance()); // Orders ApplicationContext.register(OrderConverter.class, HapiOrderConverter.getInstance()); ApplicationContext.register(OrderController.class, OrderController.getInstance()); @@ -177,26 +162,6 @@ public String openApiStream(String fileName) throws IOException { return new String(openApiStream.readAllBytes(), StandardCharsets.UTF_8); } - DomainResponse handleDemographics(DomainRequest request) { - Demographics<?> demographics; - - try { - demographics = patientDemographicsController.parseDemographics(request); - convertAndSendDemographicsUsecase.convertAndSend(demographics); - } catch (FhirParseException e) { - logger.logError("Unable to parse demographics request", e); - return domainResponseHelper.constructErrorResponse(400, e); - } catch (UnableToSendMessageException e) { - logger.logError("Unable to send demographics", e); - return domainResponseHelper.constructErrorResponse(400, e); - } - - PatientDemographicsResponse patientDemographicsResponse = - new PatientDemographicsResponse(demographics); - - return domainResponseHelper.constructOkResponse(patientDemographicsResponse); - } - DomainResponse handleOrders(DomainRequest request) { return handleMessageRequest( request, diff --git a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/demographics/ConvertAndSendDemographicsUsecase.java b/etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/demographics/ConvertAndSendDemographicsUsecase.java deleted file mode 100644 index a6965578c..000000000 --- a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/demographics/ConvertAndSendDemographicsUsecase.java +++ /dev/null @@ -1,32 +0,0 @@ -package gov.hhs.cdc.trustedintermediary.etor.demographics; - -import gov.hhs.cdc.trustedintermediary.etor.messages.UnableToSendMessageException; -import gov.hhs.cdc.trustedintermediary.etor.orders.Order; -import gov.hhs.cdc.trustedintermediary.etor.orders.OrderConverter; -import gov.hhs.cdc.trustedintermediary.etor.orders.OrderSender; -import javax.inject.Inject; - -/** - * The overall logic that handles receiving patient demographics, converting it to a lab order, and - * sending it on its way. - */ -public class ConvertAndSendDemographicsUsecase { - - private static final ConvertAndSendDemographicsUsecase INSTANCE = - new ConvertAndSendDemographicsUsecase(); - - @Inject OrderConverter converter; - - @Inject OrderSender sender; - - public static ConvertAndSendDemographicsUsecase getInstance() { - return INSTANCE; - } - - private ConvertAndSendDemographicsUsecase() {} - - public void convertAndSend(Demographics<?> demographics) throws UnableToSendMessageException { - Order<?> order = converter.convertToOrder(demographics); - sender.send(order); - } -} diff --git a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/demographics/Demographics.java b/etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/demographics/Demographics.java deleted file mode 100644 index ed0e7ea5a..000000000 --- a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/demographics/Demographics.java +++ /dev/null @@ -1,14 +0,0 @@ -package gov.hhs.cdc.trustedintermediary.etor.demographics; - -import gov.hhs.cdc.trustedintermediary.etor.ruleengine.FhirResource; - -/** - * Interface to wrap a third-party demographics class (Ex: Hapi FHIR Bundle) - * - * @param <T> The underlying FHIR demographics type. - */ -public interface Demographics<T> extends FhirResource<T> { - String getFhirResourceId(); - - String getPatientId(); -} diff --git a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/demographics/PatientDemographicsController.java b/etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/demographics/PatientDemographicsController.java deleted file mode 100644 index 2110a9369..000000000 --- a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/demographics/PatientDemographicsController.java +++ /dev/null @@ -1,34 +0,0 @@ -package gov.hhs.cdc.trustedintermediary.etor.demographics; - -import gov.hhs.cdc.trustedintermediary.domainconnector.DomainRequest; -import gov.hhs.cdc.trustedintermediary.external.hapi.HapiDemographics; -import gov.hhs.cdc.trustedintermediary.wrappers.FhirParseException; -import gov.hhs.cdc.trustedintermediary.wrappers.HapiFhir; -import gov.hhs.cdc.trustedintermediary.wrappers.Logger; -import javax.inject.Inject; -import org.hl7.fhir.r4.model.Bundle; - -/** - * Creates an in-memory representation of patient demographics to be ingested by the system, and - * return response information back to the client. - */ -public class PatientDemographicsController { - - private static final PatientDemographicsController PATIENT_DEMOGRAPHICS_CONTROLLER = - new PatientDemographicsController(); - - @Inject HapiFhir fhir; - @Inject Logger logger; - - private PatientDemographicsController() {} - - public static PatientDemographicsController getInstance() { - return PATIENT_DEMOGRAPHICS_CONTROLLER; - } - - public Demographics<?> parseDemographics(DomainRequest request) throws FhirParseException { - logger.logInfo("Parsing patient demographics"); - var fhirBundle = fhir.parseResource(request.getBody(), Bundle.class); - return new HapiDemographics(fhirBundle); - } -} diff --git a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/demographics/PatientDemographicsResponse.java b/etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/demographics/PatientDemographicsResponse.java deleted file mode 100644 index e56b4d597..000000000 --- a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/demographics/PatientDemographicsResponse.java +++ /dev/null @@ -1,34 +0,0 @@ -package gov.hhs.cdc.trustedintermediary.etor.demographics; - -/** Contains an ID that is reflected from the patient demographic data. */ -public class PatientDemographicsResponse { - - private String fhirResourceId; - private String patientId; - - PatientDemographicsResponse(String fhirResourceId, String patientId) { - setFhirResourceId(fhirResourceId); - setPatientId(patientId); - } - - public PatientDemographicsResponse(Demographics<?> demographics) { - setFhirResourceId(demographics.getFhirResourceId()); - setPatientId(demographics.getPatientId()); - } - - public String getFhirResourceId() { - return fhirResourceId; - } - - public void setFhirResourceId(String fhirResourceId) { - this.fhirResourceId = fhirResourceId; - } - - public String getPatientId() { - return patientId; - } - - public void setPatientId(String patientId) { - this.patientId = patientId; - } -} diff --git a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/orders/OrderConverter.java b/etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/orders/OrderConverter.java index 684652130..dee2f1447 100644 --- a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/orders/OrderConverter.java +++ b/etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/orders/OrderConverter.java @@ -1,11 +1,7 @@ package gov.hhs.cdc.trustedintermediary.etor.orders; -import gov.hhs.cdc.trustedintermediary.etor.demographics.Demographics; - /** Interface for converting things to orders and things in orders. */ public interface OrderConverter { - Order<?> convertToOrder(Demographics<?> demographics); - Order<?> convertToOmlOrder(Order<?> order); Order<?> addContactSectionToPatientResource(Order<?> order); diff --git a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/hapi/HapiDemographics.java b/etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/hapi/HapiDemographics.java deleted file mode 100644 index 4722ae76c..000000000 --- a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/hapi/HapiDemographics.java +++ /dev/null @@ -1,15 +0,0 @@ -package gov.hhs.cdc.trustedintermediary.external.hapi; - -import gov.hhs.cdc.trustedintermediary.etor.demographics.Demographics; -import org.hl7.fhir.r4.model.Bundle; - -/** - * A concrete implementation of a {@link Demographics} that uses the Hapi FHIR bundle as its - * underlying type. - */ -public class HapiDemographics extends HapiMessage implements Demographics<Bundle> { - - public HapiDemographics(Bundle innerDemographics) { - super(innerDemographics); - } -} diff --git a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/hapi/HapiOrderConverter.java b/etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/hapi/HapiOrderConverter.java index 0a2457d96..5b2439ae8 100644 --- a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/hapi/HapiOrderConverter.java +++ b/etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/hapi/HapiOrderConverter.java @@ -1,30 +1,18 @@ package gov.hhs.cdc.trustedintermediary.external.hapi; -import gov.hhs.cdc.trustedintermediary.etor.demographics.Demographics; import gov.hhs.cdc.trustedintermediary.etor.orders.Order; import gov.hhs.cdc.trustedintermediary.etor.orders.OrderConverter; import gov.hhs.cdc.trustedintermediary.wrappers.Logger; -import java.time.Instant; -import java.util.Date; import java.util.List; -import java.util.UUID; import javax.inject.Inject; import org.hl7.fhir.r4.model.Bundle; -import org.hl7.fhir.r4.model.CodeableConcept; import org.hl7.fhir.r4.model.Coding; -import org.hl7.fhir.r4.model.Identifier; import org.hl7.fhir.r4.model.MessageHeader; -import org.hl7.fhir.r4.model.Meta; import org.hl7.fhir.r4.model.Patient; -import org.hl7.fhir.r4.model.Provenance; -import org.hl7.fhir.r4.model.Reference; -import org.hl7.fhir.r4.model.ServiceRequest; -import org.hl7.fhir.r4.model.UrlType; /** - * Converts {@link Demographics} to a Hapi-specific FHIR lab order ({@link HapiOrder} or {@link - * Order <Bundle>}). Also converts an order to identify as an HL7v2 OML in the {@link - * MessageHeader}. + * Converts an order to identify as an HL7v2 OML in the {@link MessageHeader}. Also helps in moving + * around data in the order. */ public class HapiOrderConverter implements OrderConverter { private static final HapiOrderConverter INSTANCE = new HapiOrderConverter(); @@ -49,48 +37,6 @@ public static HapiOrderConverter getInstance() { private HapiOrderConverter() {} - @Override - public HapiOrder convertToOrder(final Demographics<?> demographics) { - logger.logInfo("Converting demographics to order"); - - var hapiDemographics = (Demographics<Bundle>) demographics; - var demographicsBundle = hapiDemographics.getUnderlyingResource(); - - var overallId = UUID.randomUUID().toString(); - if (!demographicsBundle.hasId()) { - demographicsBundle.setId(overallId); - } - - if (!demographicsBundle.hasIdentifier()) { - demographicsBundle.setIdentifier(new Identifier().setValue(overallId)); - } - - var orderDateTime = Date.from(Instant.now()); - if (!demographicsBundle.hasTimestamp()) { - demographicsBundle.setTimestamp(orderDateTime); - } - - demographicsBundle.setType( - Bundle.BundleType.MESSAGE); // it always needs to be a message, so no if statement - - var patient = - HapiHelper.resourcesInBundle(demographicsBundle, Patient.class) - .findFirst() - .orElse(null); - - var serviceRequest = createServiceRequest(patient, orderDateTime); - var messageHeader = createMessageHeader(); - var provenance = createProvenanceResource(orderDateTime); - - demographicsBundle - .getEntry() - .add(0, new Bundle.BundleEntryComponent().setResource(messageHeader)); - demographicsBundle.addEntry(new Bundle.BundleEntryComponent().setResource(serviceRequest)); - demographicsBundle.addEntry(new Bundle.BundleEntryComponent().setResource(provenance)); - - return new HapiOrder(demographicsBundle); - } - @Override public Order<?> convertToOmlOrder(Order<?> order) { logger.logInfo("Converting order to have OML metadata"); @@ -132,30 +78,6 @@ public Order<?> addContactSectionToPatientResource(Order<?> order) { return new HapiOrder(orderBundle); } - private MessageHeader createMessageHeader() { - logger.logInfo("Creating new MessageHeader"); - - var messageHeader = new MessageHeader(); - - messageHeader.setId(UUID.randomUUID().toString()); - - messageHeader.setEvent(OML_CODING); - - var meta = new Meta(); - - // Adding processing id of 'P' - meta.addTag("http://terminology.hl7.org/CodeSystem/v2-0103", "P", "Production"); - - messageHeader.setMeta(meta); - - messageHeader.setSource( - new MessageHeader.MessageSourceComponent( - new UrlType("https://reportstream.cdc.gov/")) - .setName("CDC Trusted Intermediary")); - - return messageHeader; - } - @Override public Order<?> addEtorProcessingTag(Order<?> message) { var hapiOrder = (Order<Bundle>) message; @@ -165,41 +87,4 @@ public Order<?> addEtorProcessingTag(Order<?> message) { return new HapiOrder(messageBundle); } - - private ServiceRequest createServiceRequest(final Patient patient, final Date orderDateTime) { - logger.logInfo("Creating new ServiceRequest"); - - var serviceRequest = new ServiceRequest(); - - serviceRequest.setId(UUID.randomUUID().toString()); - - serviceRequest.setStatus(ServiceRequest.ServiceRequestStatus.ACTIVE); - - serviceRequest.setIntent(ServiceRequest.ServiceRequestIntent.ORDER); - - serviceRequest.setCode( - new CodeableConcept( - new Coding("http://loinc.org", "54089-8", "Newborn Screening Panel"))); - - serviceRequest.addCategory( - new CodeableConcept( - new Coding("http://snomed.info/sct", "108252007", "Laboratory procedure"))); - - serviceRequest.setSubject(new Reference(patient)); - - serviceRequest.setAuthoredOn(orderDateTime); - - return serviceRequest; - } - - private Provenance createProvenanceResource(Date orderDate) { - logger.logInfo("Creating new Provenance"); - var provenance = new Provenance(); - - provenance.setId(UUID.randomUUID().toString()); - provenance.setRecorded(orderDate); - provenance.setActivity(new CodeableConcept(OML_CODING)); - - return provenance; - } } diff --git a/etor/src/main/resources/openapi_etor.yaml b/etor/src/main/resources/openapi_etor.yaml index 0d24eef42..76dbefe75 100644 --- a/etor/src/main/resources/openapi_etor.yaml +++ b/etor/src/main/resources/openapi_etor.yaml @@ -12,37 +12,6 @@ externalDocs: description: Trusted Intermediary Repository url: https://github.com/CDCgov/trusted-intermediary paths: - /v1/etor/demographics: - post: - summary: Forwards demographic information to a lab - requestBody: - description: A FHIR patient resource wrapped in a FHIR Bundle - content: - application/json: - schema: - $ref: 'https://github.com/LinuxForHealth/FHIR/blob/main/fhir-openapi/src/main/webapp/META-INF/openapi.json?raw=true#/components/schemas/Bundle' - required: true - security: - - bearerAuthorization: [ ] - responses: - '200': - description: The demographics were sent successfully - content: - application/json: - schema: - $ref: '#/components/schemas/PatientDemographicsResponse' - '400': - description: Unable to parse demographics request - content: - application/json: - schema: - $ref: '#/components/schemas/BadRequestError' - '401': - description: Authentication failed due to invalid token or unknown organization - content: - application/json: - schema: - $ref: '#/components/schemas/UnauthorizedRequestError' /v1/etor/orders: post: summary: Forwards orders to a lab @@ -162,15 +131,6 @@ paths: $ref: '#/components/schemas/UnauthorizedRequestError' components: schemas: - PatientDemographicsResponse: - type: object - properties: - fhirResourceId: - type: string - example: Patient/infant-twin-1 - patientId: - type: string - example: MRN7465737865 OrdersResponse: type: object properties: diff --git a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/DemographicsMock.groovy b/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/DemographicsMock.groovy deleted file mode 100644 index 86fd2c319..000000000 --- a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/DemographicsMock.groovy +++ /dev/null @@ -1,35 +0,0 @@ -package gov.hhs.cdc.trustedintermediary - -import gov.hhs.cdc.trustedintermediary.etor.demographics.Demographics - -/** - * A mock implementation of the {@link Demographics} interface that is easy to use in tests. - */ -class DemographicsMock<T> implements Demographics<T> { - - private String fhirResourceId - private String patientId - private T underlyingDemographics - - - DemographicsMock(String fhirResourceId, String patientId, T underlyingDemographics) { - this.fhirResourceId = fhirResourceId - this.patientId = patientId - this.underlyingDemographics = underlyingDemographics - } - - @Override - T getUnderlyingResource() { - return underlyingDemographics - } - - @Override - String getFhirResourceId() { - return fhirResourceId - } - - @Override - String getPatientId() { - return patientId - } -} diff --git a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/EtorDomainRegistrationTest.groovy b/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/EtorDomainRegistrationTest.groovy index 724e185ba..5d8041211 100644 --- a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/EtorDomainRegistrationTest.groovy +++ b/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/EtorDomainRegistrationTest.groovy @@ -1,6 +1,6 @@ package gov.hhs.cdc.trustedintermediary.etor -import gov.hhs.cdc.trustedintermediary.DemographicsMock + import gov.hhs.cdc.trustedintermediary.OrderMock import gov.hhs.cdc.trustedintermediary.ResultMock import gov.hhs.cdc.trustedintermediary.context.TestApplicationContext @@ -9,13 +9,8 @@ import gov.hhs.cdc.trustedintermediary.domainconnector.DomainResponse import gov.hhs.cdc.trustedintermediary.domainconnector.DomainResponseHelper import gov.hhs.cdc.trustedintermediary.domainconnector.HttpEndpoint import gov.hhs.cdc.trustedintermediary.domainconnector.UnableToReadOpenApiSpecificationException -import gov.hhs.cdc.trustedintermediary.etor.demographics.ConvertAndSendDemographicsUsecase -import gov.hhs.cdc.trustedintermediary.etor.demographics.Demographics -import gov.hhs.cdc.trustedintermediary.etor.demographics.PatientDemographicsController -import gov.hhs.cdc.trustedintermediary.etor.demographics.PatientDemographicsResponse import gov.hhs.cdc.trustedintermediary.etor.messages.MessageHdDataType import gov.hhs.cdc.trustedintermediary.etor.messages.MessageRequestHandler -import gov.hhs.cdc.trustedintermediary.etor.messages.UnableToSendMessageException import gov.hhs.cdc.trustedintermediary.etor.metadata.partner.PartnerMetadata import gov.hhs.cdc.trustedintermediary.etor.metadata.partner.PartnerMetadataConverter import gov.hhs.cdc.trustedintermediary.etor.metadata.partner.PartnerMetadataException @@ -49,7 +44,6 @@ class EtorDomainRegistrationTest extends Specification { def "domain registration has endpoints"() { given: def domainRegistration = new EtorDomainRegistration() - def demographicsEndpoint = new HttpEndpoint("POST", EtorDomainRegistration.DEMOGRAPHICS_API_ENDPOINT, true) def ordersEndpoint = new HttpEndpoint("POST", EtorDomainRegistration.ORDERS_API_ENDPOINT, true) def metadataEndpoint = new HttpEndpoint("GET", EtorDomainRegistration.METADATA_API_ENDPOINT, true) def consolidatedOrdersEndpoint = new HttpEndpoint("GET", EtorDomainRegistration.CONSOLIDATED_SUMMARY_API_ENDPOINT, true) @@ -59,7 +53,6 @@ class EtorDomainRegistrationTest extends Specification { then: !endpoints.isEmpty() - endpoints.get(demographicsEndpoint) != null endpoints.get(ordersEndpoint) != null endpoints.get(metadataEndpoint) != null endpoints.get(consolidatedOrdersEndpoint) != null @@ -68,7 +61,6 @@ class EtorDomainRegistrationTest extends Specification { def "domain registration has endpoints when DB_URL is not found"() { given: def domainRegistration = new EtorDomainRegistration() - def demographicsEndpoint = new HttpEndpoint("POST", EtorDomainRegistration.DEMOGRAPHICS_API_ENDPOINT, true) def ordersEndpoint = new HttpEndpoint("POST", EtorDomainRegistration.ORDERS_API_ENDPOINT, true) def metadataEndpoint = new HttpEndpoint("GET", EtorDomainRegistration.METADATA_API_ENDPOINT, true) def consolidatedOrdersEndpoint = new HttpEndpoint("GET", EtorDomainRegistration.CONSOLIDATED_SUMMARY_API_ENDPOINT, true) @@ -79,7 +71,6 @@ class EtorDomainRegistrationTest extends Specification { then: !endpoints.isEmpty() - endpoints.get(demographicsEndpoint) != null endpoints.get(ordersEndpoint) != null endpoints.get(metadataEndpoint) != null endpoints.get(consolidatedOrdersEndpoint) != null @@ -122,95 +113,6 @@ class EtorDomainRegistrationTest extends Specification { thrown(IOException) } - def "stitches the demographics parsing to the response construction"() { - given: - def domainRegistration = new EtorDomainRegistration() - - def mockDemographicsController = Mock(PatientDemographicsController) - def mockResponseHelper = Mock(DomainResponseHelper) - - def mockRequestId = "asdf-12341-jkl-7890" - - mockDemographicsController.parseDemographics(_ as DomainRequest) >> new DemographicsMock(mockRequestId, "a patient ID", "demographics") - mockResponseHelper.constructOkResponse(_ as PatientDemographicsResponse) >> new DomainResponse(418) - - def mockUseCase = Mock(ConvertAndSendDemographicsUsecase) - - TestApplicationContext.register(EtorDomainRegistration, domainRegistration) - TestApplicationContext.register(PatientDemographicsController, mockDemographicsController) - TestApplicationContext.register(ConvertAndSendDemographicsUsecase, mockUseCase) - TestApplicationContext.register(DomainResponseHelper, mockResponseHelper) - TestApplicationContext.injectRegisteredImplementations() - - def domainRequest = new DomainRequest() - - when: - domainRegistration.handleDemographics(domainRequest) - - then: - 1 * mockResponseHelper.constructOkResponse(_ as PatientDemographicsResponse) >> { PatientDemographicsResponse demographicsResponse -> - assert demographicsResponse.fhirResourceId == mockRequestId - } - 1 * mockUseCase.convertAndSend(_ as Demographics) - } - - def "handleDemographics generates an error response when the usecase throws an exception"() { - given: - def expectedStatusCode = 400 - - def domainRegistration = new EtorDomainRegistration() - TestApplicationContext.register(EtorDomainRegistration, domainRegistration) - - def mockController = Mock(PatientDemographicsController) - mockController.parseDemographics(_ as DomainRequest) >> new DemographicsMock<?>(null, null, null) - TestApplicationContext.register(PatientDemographicsController, mockController) - - def mockUseCase = Mock(ConvertAndSendDemographicsUsecase) - mockUseCase.convertAndSend(_ as Demographics<?>) >> { - throw new UnableToSendMessageException("error", new NullPointerException()) - } - TestApplicationContext.register(ConvertAndSendDemographicsUsecase, mockUseCase) - - def mockResponseHelper = Mock(DomainResponseHelper) - mockResponseHelper.constructErrorResponse(expectedStatusCode, _ as Exception) >> new DomainResponse(expectedStatusCode) - TestApplicationContext.register(DomainResponseHelper, mockResponseHelper) - - TestApplicationContext.injectRegisteredImplementations() - - when: - def res = domainRegistration.handleDemographics(new DomainRequest()) - def actualStatusCode = res.statusCode - - then: - actualStatusCode == expectedStatusCode - } - - def "handlesDemographics throws 400 error when a FhirParseException is triggered"() { - - given: - def expectedStatusCode = 400 - def domainRegistration = new EtorDomainRegistration() - TestApplicationContext.register(EtorDomainRegistration, domainRegistration) - def mockRequest = new DomainRequest() - def message = "Something blew up!" - def cause = new IllegalArgumentException() - def fhirParseException = new FhirParseException(message, cause) - def mockPatientDemographicsController = Mock(PatientDemographicsController) - mockPatientDemographicsController.parseDemographics(mockRequest) >> { throw fhirParseException } - TestApplicationContext.register(PatientDemographicsController, mockPatientDemographicsController) - def mockHelper = Mock(DomainResponseHelper) - mockHelper.constructErrorResponse(expectedStatusCode, fhirParseException) >> { new DomainResponse(expectedStatusCode)} - TestApplicationContext.register(DomainResponseHelper, mockHelper) - TestApplicationContext.injectRegisteredImplementations() - - when: - def res = domainRegistration.handleDemographics(mockRequest) - def actualStatusCode = res.getStatusCode() - - then: - actualStatusCode == expectedStatusCode - } - def "handleOrders happy path"() { given: def orderMock = new OrderMock<?>("resource id", "a patient ID", "orders", null, null, null, null, null) diff --git a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/demographics/ConvertAndSendDemographicsUsecaseTest.groovy b/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/demographics/ConvertAndSendDemographicsUsecaseTest.groovy deleted file mode 100644 index c1908bdbc..000000000 --- a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/demographics/ConvertAndSendDemographicsUsecaseTest.groovy +++ /dev/null @@ -1,38 +0,0 @@ -package gov.hhs.cdc.trustedintermediary.etor.demographics - -import gov.hhs.cdc.trustedintermediary.DemographicsMock -import gov.hhs.cdc.trustedintermediary.OrderMock -import gov.hhs.cdc.trustedintermediary.context.TestApplicationContext -import gov.hhs.cdc.trustedintermediary.etor.orders.OrderConverter -import gov.hhs.cdc.trustedintermediary.etor.orders.OrderSender - -import spock.lang.Specification - -class ConvertAndSendDemographicsUsecaseTest extends Specification { - - def setup() { - TestApplicationContext.reset() - TestApplicationContext.init() - TestApplicationContext.register(ConvertAndSendDemographicsUsecase, ConvertAndSendDemographicsUsecase.getInstance()) - } - - def "ConvertAndSend"() { - given: - def mockOrder = new OrderMock(null, null, null, null, null, null, null, null) - def mockConverter = Mock(OrderConverter) - def mockSender = Mock(OrderSender) - - TestApplicationContext.register(OrderConverter, mockConverter) - TestApplicationContext.register(OrderSender, mockSender) - TestApplicationContext.injectRegisteredImplementations() - - def demographics = new DemographicsMock(null, null, null) - - when: - ConvertAndSendDemographicsUsecase.getInstance().convertAndSend(demographics) - - then: - 1 * mockConverter.convertToOrder(_ as Demographics) >> mockOrder - 1 * mockSender.send(mockOrder) - } -} diff --git a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/demographics/PatientDemographicsControllerTest.groovy b/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/demographics/PatientDemographicsControllerTest.groovy deleted file mode 100644 index e2bcddb57..000000000 --- a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/demographics/PatientDemographicsControllerTest.groovy +++ /dev/null @@ -1,49 +0,0 @@ -package gov.hhs.cdc.trustedintermediary.etor.demographics - -import gov.hhs.cdc.trustedintermediary.context.TestApplicationContext -import gov.hhs.cdc.trustedintermediary.domainconnector.DomainRequest -import gov.hhs.cdc.trustedintermediary.external.hapi.HapiMessageHelper -import gov.hhs.cdc.trustedintermediary.wrappers.FhirParseException -import gov.hhs.cdc.trustedintermediary.wrappers.HapiFhir -import org.hl7.fhir.r4.model.Bundle -import spock.lang.Specification - -class PatientDemographicsControllerTest extends Specification { - - def setup() { - TestApplicationContext.reset() - TestApplicationContext.init() - TestApplicationContext.register(HapiMessageHelper, HapiMessageHelper.getInstance()) - TestApplicationContext.register(PatientDemographicsController, PatientDemographicsController.getInstance()) - } - - def "parseDemographics gets the Bundle and puts it as the underlying demographics"() { - given: - def expectedBundle = new Bundle() - def fhir = Mock(HapiFhir) - fhir.parseResource(_ as String, _ as Class) >> expectedBundle - TestApplicationContext.register(HapiFhir, fhir) - TestApplicationContext.injectRegisteredImplementations() - - when: - def patientDemographics = PatientDemographicsController.getInstance().parseDemographics(new DomainRequest()) - - then: - patientDemographics.getUnderlyingResource() == expectedBundle - } - - def "parseDemographics throws an exception when unable to parse de request"() { - given: - def controller = PatientDemographicsController.getInstance() - def fhir = Mock(HapiFhir) - fhir.parseResource(_ as String, _ as Class) >> { throw new FhirParseException("DogCow", new NullPointerException()) } - TestApplicationContext.register(HapiFhir, fhir) - TestApplicationContext.injectRegisteredImplementations() - - when: - controller.parseDemographics(new DomainRequest()) - - then: - thrown(FhirParseException) - } -} diff --git a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/demographics/PatientDemographicsResponseTest.groovy b/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/demographics/PatientDemographicsResponseTest.groovy deleted file mode 100644 index bfa28ed6b..000000000 --- a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/demographics/PatientDemographicsResponseTest.groovy +++ /dev/null @@ -1,44 +0,0 @@ -package gov.hhs.cdc.trustedintermediary.etor.demographics - -import gov.hhs.cdc.trustedintermediary.DemographicsMock -import gov.hhs.cdc.trustedintermediary.PojoTestUtils -import spock.lang.Specification - -class PatientDemographicsResponseTest extends Specification { - - def "test getters and setters"() { - when: - PojoTestUtils.validateGettersAndSetters(PatientDemographicsResponse.class) - - then: - noExceptionThrown() - } - - def "test demographics constructor"() { - given: - def resourceId = "67890asdfg" - def patientId = "fthgyu687" - - def demographics = new DemographicsMock(resourceId, patientId, null) - - when: - def response = new PatientDemographicsResponse(demographics) - - then: - response.getFhirResourceId() == resourceId - response.getPatientId() == patientId - } - - def "test argument constructor"() { - given: - def resourceId = "67890asdfg" - def patientId = "fthgyu687" - - when: - def response = new PatientDemographicsResponse(resourceId, patientId) - - then: - response.getFhirResourceId() == resourceId - response.getPatientId() == patientId - } -} diff --git a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/hapi/HapiDemographicsTest.groovy b/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/hapi/HapiDemographicsTest.groovy deleted file mode 100644 index cedd255c3..000000000 --- a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/hapi/HapiDemographicsTest.groovy +++ /dev/null @@ -1,61 +0,0 @@ -package gov.hhs.cdc.trustedintermediary.external.hapi - -import gov.hhs.cdc.trustedintermediary.context.TestApplicationContext -import gov.hhs.cdc.trustedintermediary.wrappers.HapiFhir -import org.hl7.fhir.r4.model.Bundle -import org.hl7.fhir.r4.model.CodeableConcept -import org.hl7.fhir.r4.model.Coding -import org.hl7.fhir.r4.model.Identifier -import org.hl7.fhir.r4.model.Patient -import spock.lang.Specification - -class HapiDemographicsTest extends Specification { - - def setup() { - TestApplicationContext.reset() - TestApplicationContext.init() - TestApplicationContext.register(HapiMessageHelper.class, HapiMessageHelper.getInstance()) - TestApplicationContext.injectRegisteredImplementations() - } - - def "getUnderlyingResource works"() { - given: - def expectedInnerDemographics = new Bundle() - def demographics = new HapiDemographics(expectedInnerDemographics) - - when: - def actualInnerDemographics = demographics.getUnderlyingResource() - - then: - actualInnerDemographics == expectedInnerDemographics - } - - def "getFhirResourceId works"() { - given: - def expectedId = "DogCow goes Moof" - def innerDemographics = new Bundle() - innerDemographics.setId(expectedId) - - when: - def demographics = new HapiDemographics(innerDemographics) - - then: - demographics.getFhirResourceId() == expectedId - } - - def "getPatientId works"() { - given: - def expectedPatientId = "DogCow goes Moof" - def innerDemographics = new Bundle() - def patient = new Patient().addIdentifier(new Identifier() - .setValue(expectedPatientId) - .setType(new CodeableConcept().addCoding(new Coding("http://terminology.hl7.org/CodeSystem/v2-0203", "MR", "Medical Record Number")))) - innerDemographics.addEntry(new Bundle.BundleEntryComponent().setResource(patient)) - - when: - def demographics = new HapiDemographics(innerDemographics) - - then: - demographics.getPatientId() == expectedPatientId - } -} diff --git a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/hapi/HapiOrderConverterTest.groovy b/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/hapi/HapiOrderConverterTest.groovy index bbac342cb..a2d041530 100644 --- a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/hapi/HapiOrderConverterTest.groovy +++ b/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/hapi/HapiOrderConverterTest.groovy @@ -1,30 +1,22 @@ package gov.hhs.cdc.trustedintermediary.external.hapi -import gov.hhs.cdc.trustedintermediary.DemographicsMock import gov.hhs.cdc.trustedintermediary.OrderMock import gov.hhs.cdc.trustedintermediary.context.TestApplicationContext import gov.hhs.cdc.trustedintermediary.etor.orders.OrderConverter import org.hl7.fhir.r4.model.Address +import org.hl7.fhir.r4.model.Bundle +import org.hl7.fhir.r4.model.Coding import org.hl7.fhir.r4.model.ContactPoint import org.hl7.fhir.r4.model.Extension import org.hl7.fhir.r4.model.HumanName -import org.hl7.fhir.r4.model.StringType - -import java.time.Instant -import org.hl7.fhir.r4.model.Bundle -import org.hl7.fhir.r4.model.Coding -import org.hl7.fhir.r4.model.Identifier import org.hl7.fhir.r4.model.MessageHeader import org.hl7.fhir.r4.model.Patient -import org.hl7.fhir.r4.model.Provenance -import org.hl7.fhir.r4.model.ServiceRequest +import org.hl7.fhir.r4.model.StringType import spock.lang.Specification class HapiOrderConverterTest extends Specification { Patient mockPatient - Bundle mockDemographicsBundle - DemographicsMock<Bundle> mockDemographics Bundle mockOrderBundle OrderMock<Bundle> mockOrder @@ -37,117 +29,11 @@ class HapiOrderConverterTest extends Specification { TestApplicationContext.injectRegisteredImplementations() mockPatient = new Patient() - mockDemographicsBundle = new Bundle().addEntry(new Bundle.BundleEntryComponent().setResource(mockPatient)) - mockDemographics = new DemographicsMock("fhirResourceId", "patientId", mockDemographicsBundle) mockOrderBundle = new Bundle().addEntry(new Bundle.BundleEntryComponent().setResource(mockPatient)) mockOrder = new OrderMock("fhirResourceId", "patientId", mockOrderBundle, null, null, null, null, null) } - def "the converter fills in gaps of any missing data in the Bundle"() { - - when: - def orderBundle = HapiOrderConverter.getInstance().convertToOrder(mockDemographics).getUnderlyingResource() - - then: - orderBundle.hasId() - orderBundle.hasIdentifier() - orderBundle.hasTimestamp() - orderBundle.getType() == Bundle.BundleType.MESSAGE - orderBundle.getId() == orderBundle.getIdentifier().getValue() - } - - def "the converter doesn't change things if it is already set"() { - given: - def mockId = "an id" - mockDemographicsBundle.setId(mockId) - def mockIdentifier = "an identifier" - mockDemographicsBundle.setIdentifier(new Identifier().setValue(mockIdentifier)) - def mockTimestamp = Date.from(Instant.now().minusSeconds(60)) - mockDemographicsBundle.setTimestamp(mockTimestamp) - - when: - def orderBundle = HapiOrderConverter.getInstance().convertToOrder(mockDemographics).getUnderlyingResource() - - then: - orderBundle.getId() == mockId - orderBundle.getIdentifier().getValue() == mockIdentifier - orderBundle.getTimestamp() == mockTimestamp - orderBundle.getId() != orderBundle.getIdentifier().getValue() - } - - def "the converter always changes the bundle type to message"() { - given: - mockDemographicsBundle.setType(Bundle.BundleType.COLLECTION) - - when: - def orderBundle = HapiOrderConverter.getInstance().convertToOrder(mockDemographics).getUnderlyingResource() - - then: - orderBundle.getType() == Bundle.BundleType.MESSAGE - } - - def "the demographics correctly constructs a message header in the lab order"() { - - when: - def orderBundle = HapiOrderConverter.getInstance().convertToOrder(mockDemographics).getUnderlyingResource() - - then: - def messageHeader = orderBundle.getEntry().get(0).getResource() as MessageHeader - - messageHeader.hasId() - messageHeader.getMeta().getTag().system[0] == "http://terminology.hl7.org/CodeSystem/v2-0103" - messageHeader.getMeta().getTag().code[0] == "P" - messageHeader.getMeta().getTag().display[0] == "Production" - messageHeader.getEventCoding().getSystem() == "http://terminology.hl7.org/CodeSystem/v2-0003" - messageHeader.getEventCoding().getCode() == "O21" - messageHeader.getSource().getName() == "CDC Trusted Intermediary" - messageHeader.getSource().getEndpoint() == "https://reportstream.cdc.gov/" - } - - def "the converter correctly reuses the patient from the passed in demographics"() { - - when: - def orderBundle = HapiOrderConverter.getInstance().convertToOrder(mockDemographics).getUnderlyingResource() - - then: - def patient = orderBundle.getEntry().get(1).getResource() as Patient - - patient == mockPatient - } - - def "the converter correctly constructs a service request in the lab order"() { - - when: - def orderBundle = HapiOrderConverter.getInstance().convertToOrder(mockDemographics).getUnderlyingResource() - - then: - def serviceRequest = orderBundle.getEntry().get(2).getResource() as ServiceRequest - - serviceRequest.hasId() - serviceRequest.getCode().getCodingFirstRep().getCode() == "54089-8" - serviceRequest.getCategoryFirstRep().getCodingFirstRep().getCode() == "108252007" - serviceRequest.getSubject().getResource() == orderBundle.getEntry().get(1).getResource() - serviceRequest.hasAuthoredOn() - } - - def "the order datetime should match for bundle, service request, and provenance resources"() { - - when: - def orderBundle = HapiOrderConverter.getInstance().convertToOrder(mockDemographics).getUnderlyingResource() - def bundleDateTime = orderBundle.getTimestamp() - def serviceRequest = orderBundle.getEntry().get(2).getResource() as ServiceRequest - def provenance = orderBundle.getEntry().get(3).getResource() as Provenance - - then: - def serviceRequestDateTime = serviceRequest.getAuthoredOn() - def provenanceDateTime = provenance.getRecorded() - - bundleDateTime == serviceRequestDateTime - bundleDateTime == provenanceDateTime - serviceRequestDateTime == provenanceDateTime - } - def "convert the pre-existing message header to specify OML"() { given: mockOrderBundle.addEntry( From 660dd61d373c3d3f79432606a9bbaf4adc8693df Mon Sep 17 00:00:00 2001 From: halprin <halprin@users.noreply.github.com> Date: Wed, 8 May 2024 10:06:15 -0600 Subject: [PATCH 2/5] delete the demographic stuff from the IG --- ig/input/fsh/logical-adt-01.fsh | 25 ------------------------- 1 file changed, 25 deletions(-) delete mode 100644 ig/input/fsh/logical-adt-01.fsh diff --git a/ig/input/fsh/logical-adt-01.fsh b/ig/input/fsh/logical-adt-01.fsh deleted file mode 100644 index 27a906bd2..000000000 --- a/ig/input/fsh/logical-adt-01.fsh +++ /dev/null @@ -1,25 +0,0 @@ -// defines the ADT-01 input that is expected for newborn screening - -Logical: ADT01 -Id: adt-01-logical-model -Title: "ADT-01" -Description: "The expected input for the demographic data for the newborn screening ETOR workflow" -* MSH 1..1 MSHSegment "MSH segment" -* EVN 1..1 EVNSegment "EVN segment" -* PID 1..1 PIDSegment "PID segment" -* messageString 0..1 string "the full message as delimeted text" - - -// Provenance Section begins -Instance: adt01-initial-history-create -InstanceOf: Provenance -Title: "Initial creation of ADT01 message changelog" -Usage: #definition -* target[+] = Reference(StructureDefinition/adt-01-logical-model) -* recorded = "2023-08-29T17:26:36.0000Z" -* occurredDateTime = "2023-08-29" -* reason = http://terminology.hl7.org/CodeSystem/v3-ActReason#METAMGT -* reason.text = "Created an ADT message resource" -* activity = http://terminology.hl7.org/CodeSystem/v3-DataOperation#CREATE -* agent[+].type = http://terminology.hl7.org/CodeSystem/provenance-participant-type#author -* agent[=].who.display = "T. R. Johnson" From 4046961281a53b2b251ae3ceef3e208934fdf126 Mon Sep 17 00:00:00 2001 From: halprin <halprin@users.noreply.github.com> Date: Wed, 8 May 2024 10:13:39 -0600 Subject: [PATCH 3/5] Delete extra line --- .../trustedintermediary/etor/EtorDomainRegistrationTest.groovy | 1 - 1 file changed, 1 deletion(-) diff --git a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/EtorDomainRegistrationTest.groovy b/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/EtorDomainRegistrationTest.groovy index 5d8041211..dda90c6c0 100644 --- a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/EtorDomainRegistrationTest.groovy +++ b/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/EtorDomainRegistrationTest.groovy @@ -1,6 +1,5 @@ package gov.hhs.cdc.trustedintermediary.etor - import gov.hhs.cdc.trustedintermediary.OrderMock import gov.hhs.cdc.trustedintermediary.ResultMock import gov.hhs.cdc.trustedintermediary.context.TestApplicationContext From ee366923414829bf191613b97ea139a1aa1f324a Mon Sep 17 00:00:00 2001 From: halprin <halprin@users.noreply.github.com> Date: Wed, 8 May 2024 10:17:14 -0600 Subject: [PATCH 4/5] delete demographics from the load tests --- operations/locustfile.py | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/operations/locustfile.py b/operations/locustfile.py index 8c9ca8ab4..f9cc75a45 100644 --- a/operations/locustfile.py +++ b/operations/locustfile.py @@ -10,13 +10,11 @@ HEALTH_ENDPOINT = "/health" AUTH_ENDPOINT = "/v1/auth/token" -DEMOGRAPHICS_ENDPOINT = "/v1/etor/demographics" ORDERS_ENDPOINT = "/v1/etor/orders" RESULTS_ENDPOINT = "/v1/etor/results" METADATA_ENDPOINT = "/v1/etor/metadata" CONSOLIDATED_ENDPOINT = "/v1/etor/metadata/summary" -demographics_request_body = None order_request_body = None result_request_body = None auth_request_body = None @@ -58,14 +56,6 @@ def authenticate(self): def get_health(self): self.client.get(HEALTH_ENDPOINT) - @task(5) - def post_v1_etor_demographics(self): - self.client.post( - DEMOGRAPHICS_ENDPOINT, - data=demographics_request_body, - headers={"Authorization": self.access_token}, - ) - @task(5) def post_v1_etor_orders(self): response = self.client.post( @@ -112,7 +102,6 @@ def get_v1_metadata_consolidated(self): @events.test_start.add_listener def test_start(environment): - global demographics_request_body global auth_request_body global order_request_body global result_request_body @@ -121,7 +110,6 @@ def test_start(environment): # in a distributed run, the master does not typically need any test data return - demographics_request_body = get_demographics_request_body() auth_request_body = get_auth_request_body() order_request_body = get_orders_request_body() result_request_body = get_results_request_body() @@ -151,12 +139,6 @@ def get_auth_request_body(): return params.encode("utf-8") -def get_demographics_request_body(): - # read the sample request body for the demographics endpoint - with open("examples/Test/e2e/demographics/001_Patient_NBS.fhir", "r") as f: - return f.read() - - def get_orders_request_body(): # read the sample request body for the orders endpoint with open("examples/Test/e2e/orders/001_OML_O21_short.fhir", "r") as f: From 1017afe1325c001849296ac23767096dd66fb9e9 Mon Sep 17 00:00:00 2001 From: halprin <halprin@users.noreply.github.com> Date: Wed, 8 May 2024 10:20:18 -0600 Subject: [PATCH 5/5] Update ADR 13 to not reference demographics --- adr/013-wrapped-domain-objects.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adr/013-wrapped-domain-objects.md b/adr/013-wrapped-domain-objects.md index d0408628a..f05fb33e2 100644 --- a/adr/013-wrapped-domain-objects.md +++ b/adr/013-wrapped-domain-objects.md @@ -18,7 +18,7 @@ We typically isolate libraries by creating an Interface at the library boundary. Our business logic can then use the wrapper Interface without needing to know the actual underlying implementation, and that implementation can be changed without changing the Interface that the business logic relies on. -You can see an example of this in [Demographics.java](../app/src/main/java/gov/hhs/cdc/trustedintermediary/etor/demographics/Demographics.java) (the interface) and [HapiDemographics.java](../app/src/main/java/gov/hhs/cdc/trustedintermediary/external/hapi/HapiDemographics.java) (the implementation). +You can see an example of this in [Order.java](../etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/orders/Order.java) (the interface) and [HapiOrder.java](../etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/hapi/HapiOrder.java) (the implementation). ### Related Issues