Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ETOR Processing Tag #844

Merged
merged 46 commits into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
c8b49cb
added meta tag of etor processing
jorg3lopez Feb 5, 2024
a3177bd
Merge branch 'bug-fix-credentials-folder' into stream2-add-processing…
jorg3lopez Feb 5, 2024
6b1d825
ETOR processing tag for orders
jorg3lopez Feb 5, 2024
7df3138
fix failing test cases
jorg3lopez Feb 5, 2024
30bc7e6
fixed double entry
jorg3lopez Feb 5, 2024
d258a74
fixed HapiOrderConverter unit test
jorg3lopez Feb 5, 2024
1e3e56a
fixed top level tag entry
jorg3lopez Feb 5, 2024
ab3239a
fixed e2e: OrderTest failures
jorg3lopez Feb 5, 2024
3f605e9
Add run config file
saquino0827 Feb 5, 2024
56f6b25
Merge branch 'bug-fix-credentials-folder' into stream2-add-processing…
jorg3lopez Feb 6, 2024
7a525e4
changes:
jorg3lopez Feb 6, 2024
c0c4bdf
Add result converter and use case for adding TI identifier to message…
saquino0827 Feb 5, 2024
c63b792
Add test coverage
saquino0827 Feb 6, 2024
d0672f4
Add more unit test coverage
saquino0827 Feb 6, 2024
35e51e3
Merge branch 'main' into stream2-add-processing-tag-to-message
saquino0827 Feb 6, 2024
667f8d4
Merge branch 'main' into stream2-add-processing-tag-to-message
saquino0827 Feb 6, 2024
5bc58a5
Merge branch 'main' into stream2-add-processing-tag-to-message
jorg3lopez Feb 7, 2024
eff01cc
Missing test coverage for HapiResult
saquino0827 Feb 8, 2024
e1dcf79
Remove unused import
saquino0827 Feb 8, 2024
4170cc5
refactoring of unit tests and format
jorg3lopez Feb 8, 2024
f14f6aa
Refacotr etor tagging into message converter helper
saquino0827 Feb 9, 2024
ee8f373
Add unit test for HapiMessageConverterHelper
saquino0827 Feb 9, 2024
75028e4
Merge branch 'main' into stream2-add-processing-tag-to-message
jorg3lopez Feb 9, 2024
04f41ea
Update HapiMessageConverterHelper to create a MessageHeader if one is…
saquino0827 Feb 9, 2024
707ca14
merge conflict fixes
saquino0827 Feb 9, 2024
4b92a37
group implementations
jorg3lopez Feb 9, 2024
67cc3a3
registered ResultConverter
jorg3lopez Feb 9, 2024
e5389d2
registered HapiMessageConverter
jorg3lopez Feb 9, 2024
21524b4
registered HapiMessageConverter
jorg3lopez Feb 9, 2024
c9386d1
Merge branch 'stream2-add-processing-tag-to-message' of https://githu…
saquino0827 Feb 9, 2024
9012bbb
cleanup messageHeader creation and add coverage
saquino0827 Feb 9, 2024
0335f6f
Add test coverage
saquino0827 Feb 9, 2024
c370427
Remove unused variable and import
saquino0827 Feb 9, 2024
0585e47
Spotless apply catch
saquino0827 Feb 9, 2024
cfe72a2
var to hold the converted result
jorg3lopez Feb 9, 2024
267189e
metadataStep enum refactoring
jorg3lopez Feb 9, 2024
dce2283
deleted spacing
jorg3lopez Feb 9, 2024
d3457e5
javadocs
jorg3lopez Feb 9, 2024
903a760
added section for the remote jvm that's attached to the project, in R…
jorg3lopez Feb 9, 2024
29a6032
edit typos
jorg3lopez Feb 9, 2024
cd0fc70
e2e: verification of ETOR metadata tag in orders
jorg3lopez Feb 10, 2024
daa7512
added comments in the RS resut sender for work needed
jorg3lopez Feb 10, 2024
4b81d65
nulled out the mockBundle for safety
jorg3lopez Feb 12, 2024
8ccba00
Merge branch 'main' into stream2-add-processing-tag-to-message
jorg3lopez Feb 12, 2024
74a6c6b
Merge branch 'main' into stream2-add-processing-tag-to-message
basiliskus Feb 12, 2024
e91aae1
Merge branch 'main' into stream2-add-processing-tag-to-message
jorg3lopez Feb 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .run/Debug TI.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!--Configuration settings to add to IntelliJ for debugging the application when running in docker container-->
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Debug TI" type="Remote">
<option name="USE_SOCKET_TRANSPORT" value="true" />
<option name="SERVER_MODE" value="false" />
<option name="SHMEM_ADDRESS" />
<option name="HOST" value="localhost" />
<option name="PORT" value="6006" />
<option name="AUTO_RESTART" value="false" />
<RunnerSettings RunnerId="Debug">
<option name="DEBUG_PORT" value="6006" />
<option name="LOCAL" value="false" />
</RunnerSettings>
<method v="2" />
</configuration>
</component>
8 changes: 4 additions & 4 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -138,23 +138,23 @@
"filename": "README.md",
"hashed_secret": "367e3228ed16bf72b36de9a4134ee8b825cafacb",
"is_verified": false,
"line_number": 279,
"line_number": 285,
"is_secret": false
},
{
"type": "Secret Keyword",
"filename": "README.md",
"hashed_secret": "40bd7d88eae0468b048e62e1056ac390970b2b51",
"is_verified": false,
"line_number": 284,
"line_number": 290,
"is_secret": false
},
{
"type": "Secret Keyword",
"filename": "README.md",
"hashed_secret": "0d46754ae17642645ca041edaac9a1c1569f5edc",
"is_verified": false,
"line_number": 289,
"line_number": 295,
"is_secret": false
}
],
Expand Down Expand Up @@ -269,5 +269,5 @@
}
]
},
"generated_at": "2024-02-09T15:36:39Z"
"generated_at": "2024-02-09T23:44:14Z"
}
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,12 @@ the swarm parameters for the test and the local url where the app is running

### Debugging

#### Attached JVM Config for IntelliJ
The project comes with an attached remote jvm configuration for debuging the container.
If you check your remote JVM settings, under `Run/Edit Configurations`,
you will see the `Debug TI`. If you want to add a new remote JVM configuration, follow the steps below,
under "**Docker Container Debugging Using Java Debug Wire Protocal**"

#### Docker Container Debugging Using Java Debug Wire Protocal (JDWP)

Go into the `Dockerfile` file and change `CMD ["java", "-jar", "app.jar"]` to `CMD ["java", "-agentlib:jdwp=transport=dt_socket,address=*:6006,server=y,suspend=n", "-jar", "app.jar"]`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,27 @@ class OrderTest extends Specification {
parsedSentPayload.entry[24].resource.contact.name.text.contains("SADIE S SMITH")
}

def "check that ETOR processing code is added to the order before sending to report stream"() {
jorg3lopez marked this conversation as resolved.
Show resolved Hide resolved
given:
var loginFirst = true
def expectedSystem = "http://localcodes.org/ETOR"
def expectedCode = "ETOR"
def expectedDisplay = "Processed by ETOR"

when:
orderClient.submit(labOrderJsonFileString, submissionId, loginFirst)
def sentPayload = SentPayloadReader.read()
def parsedSentPayLoad = JsonParsing.parse(sentPayload)
def actualSystem = parsedSentPayLoad.entry[0].resource.meta.tag[1].system
def actualCode = parsedSentPayLoad.entry[0].resource.meta.tag[1].code
def actualDisplay = parsedSentPayLoad.entry[0].resource.meta.tag[1].display

then:
actualSystem == expectedSystem
actualCode == expectedCode
actualDisplay == expectedDisplay
}

def "check that the rest of the message is unchanged except the parts we changed"() {
when:
orderClient.submit(labOrderJsonFileString, submissionId, true)
Expand All @@ -48,10 +69,11 @@ class OrderTest extends Specification {
def parsedLabOrderJsonFile = JsonParsing.parse(labOrderJsonFileString)

then:
//test that everything else is the same except the MessageHeader's event and Patient contact
//test that everything else is the same except the MessageHeader's event, Patient contact, and etor processing tag
parsedSentPayload.entry[0].resource.remove("eventCoding")
parsedLabOrderJsonFile.entry[0].resource.remove("eventCoding")
parsedSentPayload.entry[24].resource.remove("contact")
parsedSentPayload.entry[0].resource.meta.tag.remove(1)
jorg3lopez marked this conversation as resolved.
Show resolved Hide resolved

parsedSentPayload == parsedLabOrderJsonFile
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,16 @@
import gov.hhs.cdc.trustedintermediary.etor.orders.SendOrderUseCase;
import gov.hhs.cdc.trustedintermediary.etor.results.Result;
import gov.hhs.cdc.trustedintermediary.etor.results.ResultController;
import gov.hhs.cdc.trustedintermediary.etor.results.ResultConverter;
import gov.hhs.cdc.trustedintermediary.etor.results.ResultResponse;
import gov.hhs.cdc.trustedintermediary.etor.results.ResultSender;
import gov.hhs.cdc.trustedintermediary.etor.results.SendResultUseCase;
import gov.hhs.cdc.trustedintermediary.external.database.DatabasePartnerMetadataStorage;
import gov.hhs.cdc.trustedintermediary.external.database.DbDao;
import gov.hhs.cdc.trustedintermediary.external.database.PostgresDao;
import gov.hhs.cdc.trustedintermediary.external.hapi.HapiMessageConverterHelper;
import gov.hhs.cdc.trustedintermediary.external.hapi.HapiOrderConverter;
import gov.hhs.cdc.trustedintermediary.external.hapi.HapiResultConverter;
import gov.hhs.cdc.trustedintermediary.external.localfile.FilePartnerMetadataStorage;
import gov.hhs.cdc.trustedintermediary.external.localfile.MockRSEndpointClient;
import gov.hhs.cdc.trustedintermediary.external.reportstream.ReportStreamEndpointClient;
Expand Down Expand Up @@ -90,20 +93,28 @@ 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());
ApplicationContext.register(SendOrderUseCase.class, SendOrderUseCase.getInstance());
ApplicationContext.register(OrderSender.class, ReportStreamOrderSender.getInstance());
ApplicationContext.register(
PartnerMetadataOrchestrator.class, PartnerMetadataOrchestrator.getInstance());
ApplicationContext.register(ResultSender.class, ReportStreamResultSender.getInstance());
// Results
ApplicationContext.register(ResultConverter.class, HapiResultConverter.getInstance());
ApplicationContext.register(ResultController.class, ResultController.getInstance());
ApplicationContext.register(SendResultUseCase.class, SendResultUseCase.getInstance());
ApplicationContext.register(ResultSender.class, ReportStreamResultSender.getInstance());
// Message
ApplicationContext.register(
HapiMessageConverterHelper.class, HapiMessageConverterHelper.getInstance());
// Metadata
ApplicationContext.register(
PartnerMetadataOrchestrator.class, PartnerMetadataOrchestrator.getInstance());

if (ApplicationContext.getProperty("DB_URL") != null) {
ApplicationContext.register(DbDao.class, PostgresDao.getInstance());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package gov.hhs.cdc.trustedintermediary.etor.metadata;

/** Etor specific steps from the general shared metadata steps */
/** Etor specific steps from the general shared metadata steps. Keep enum in alphabetical order */
public enum EtorMetadataStep {
RECEIVED_FROM_REPORT_STREAM,

ORDER_CONVERTED_TO_OML,

CONTACT_SECTION_ADDED_TO_PATIENT,

ETOR_PROCESSING_TAG_ADDED_TO_MESSAGE_HEADER,
ORDER_CONVERTED_TO_OML,
RECEIVED_FROM_REPORT_STREAM,
SENT_TO_REPORT_STREAM
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public interface OrderConverter {

Order<?> addContactSectionToPatientResource(Order<?> order);

Order<?> addEtorProcessingTag(Order<?> message);

FhirMetadata<?> extractPublicMetadataToOperationOutcome(
PartnerMetadata metadata, String requestedId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ public void convertAndSend(final Order<?> order, String receivedSubmissionId)
omlOrder = converter.addContactSectionToPatientResource(omlOrder);
metadata.put(order.getFhirResourceId(), EtorMetadataStep.CONTACT_SECTION_ADDED_TO_PATIENT);

omlOrder = converter.addEtorProcessingTag(omlOrder);
metadata.put(
order.getFhirResourceId(),
EtorMetadataStep.ETOR_PROCESSING_TAG_ADDED_TO_MESSAGE_HEADER);

String sentSubmissionId = sender.send(omlOrder).orElse(null);

saveSentOrderSubmissionId(receivedSubmissionId, sentSubmissionId);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package gov.hhs.cdc.trustedintermediary.etor.results;

/** Interface for converting things to results and things in results. */
public interface ResultConverter {
Result<?> addEtorProcessingTag(Result<?> message);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
/** Use case for converting and sending a lab result message. */
public class SendResultUseCase implements SendMessageUseCase<Result<?>> {
private static final SendResultUseCase INSTANCE = new SendResultUseCase();

@Inject ResultConverter converter;

@Inject ResultSender sender;

private SendResultUseCase() {}
Expand All @@ -17,6 +20,13 @@ public static SendResultUseCase getInstance() {

@Override
public void convertAndSend(Result<?> result) throws UnableToSendMessageException {
sender.send(result);

jorg3lopez marked this conversation as resolved.
Show resolved Hide resolved
// savePartnerMetadataForReceivedResult(receivedSubmissionId, result)
var convertedResult = converter.addEtorProcessingTag(result);
// metadata.put(result.getFhirResourceId(),
// EtorMetadataStep.ETOR_PROCESSING_TAG_ADDED_TO_MESSAGE_HEADER);
sender.send(convertedResult); // var bundleId = sender.send(convertedResult).orElse(null),
// thoughts?
// saveSentResultSubmissionId(receivedSubmissionId, bundleId)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package gov.hhs.cdc.trustedintermediary.external.hapi;

import gov.hhs.cdc.trustedintermediary.wrappers.Logger;
import javax.inject.Inject;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.MessageHeader;
import org.hl7.fhir.r4.model.Meta;

/**
* Helper class with a variety of utilities to use on a FHIR bundle message. It adds the 'ETOR' tag
* to a FHIR bundle of type: OML, ORU It also creates the messageHeader resource in a FHIR bundle
* message.
*/
public class HapiMessageConverterHelper {

private static final HapiMessageConverterHelper INSTANCE = new HapiMessageConverterHelper();

public static HapiMessageConverterHelper getInstance() {
return INSTANCE;
}

@Inject Logger logger;

private HapiMessageConverterHelper() {}

/**
* Adds the `ETOR` code to any message provided
*
* @param messageBundle the in coming message in a FHIR bundle
*/
public void addEtorTagToBundle(Bundle messageBundle) {
var messageHeader = findOrInitializeMessageHeader(messageBundle);
var meta = messageHeader.hasMeta() ? messageHeader.getMeta() : new Meta();

meta.addTag(new Coding("http://localcodes.org/ETOR", "ETOR", "Processed by ETOR"));
messageHeader.setMeta(meta);
}

/**
* Checks if the FHIR bundle has a messageHeader, and it creates one if it is missing
*
* @param bundle the in coming message in a FHIR bundle
* @return returns existing MessageHeader resource or a newly created one
*/
public MessageHeader findOrInitializeMessageHeader(Bundle bundle) {
var messageHeader =
HapiHelper.resourcesInBundle(bundle, MessageHeader.class).findFirst().orElse(null);
if (messageHeader == null) {
messageHeader = new MessageHeader();
bundle.addEntry(new Bundle.BundleEntryComponent().setResource(messageHeader));
}
return messageHeader;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ public class HapiOrderConverter implements OrderConverter {

@Inject Logger logger;

@Inject HapiMessageConverterHelper hapiMessageConverterHelper;

public static HapiOrderConverter getInstance() {
return INSTANCE;
}
Expand Down Expand Up @@ -99,16 +101,7 @@ public Order<?> convertToOmlOrder(Order<?> order) {

var hapiOrder = (Order<Bundle>) order;
var orderBundle = hapiOrder.getUnderlyingOrder();

var messageHeader =
HapiHelper.resourcesInBundle(orderBundle, MessageHeader.class)
.findFirst()
.orElse(null);

if (messageHeader == null) {
messageHeader = new MessageHeader();
orderBundle.addEntry(new Bundle.BundleEntryComponent().setResource(messageHeader));
}
var messageHeader = hapiMessageConverterHelper.findOrInitializeMessageHeader(orderBundle);

messageHeader.setEvent(OML_CODING);

Expand Down Expand Up @@ -152,13 +145,12 @@ private MessageHeader createMessageHeader() {

messageHeader.setEvent(OML_CODING);

messageHeader.setMeta(
new Meta()
.addTag(
new Coding(
"http://terminology.hl7.org/CodeSystem/v2-0103",
"P",
"Production")));
var meta = new Meta();

// Adding processing id of 'P'
meta.addTag("http://terminology.hl7.org/CodeSystem/v2-0103", "P", "Production");
jorg3lopez marked this conversation as resolved.
Show resolved Hide resolved
jorg3lopez marked this conversation as resolved.
Show resolved Hide resolved

messageHeader.setMeta(meta);

messageHeader.setSource(
new MessageHeader.MessageSourceComponent(
Expand All @@ -168,6 +160,16 @@ private MessageHeader createMessageHeader() {
return messageHeader;
}

@Override
public Order<?> addEtorProcessingTag(Order<?> message) {
var hapiOrder = (Order<Bundle>) message;
var messageBundle = hapiOrder.getUnderlyingOrder();

hapiMessageConverterHelper.addEtorTagToBundle(messageBundle);

return new HapiOrder(messageBundle);
}

private ServiceRequest createServiceRequest(final Patient patient, final Date orderDateTime) {
logger.logInfo("Creating new ServiceRequest");

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package gov.hhs.cdc.trustedintermediary.external.hapi;

import gov.hhs.cdc.trustedintermediary.etor.results.Result;
import gov.hhs.cdc.trustedintermediary.etor.results.ResultConverter;
import gov.hhs.cdc.trustedintermediary.wrappers.Logger;
import javax.inject.Inject;
import org.hl7.fhir.r4.model.Bundle;

/**
* Converts {@link Result} to a Hapi-specific FHIR lab result {@link Result <Bundle>}) with proper
* identifying message headers.
*/
public class HapiResultConverter implements ResultConverter {

private static final HapiResultConverter INSTANCE = new HapiResultConverter();

@Inject HapiMessageConverterHelper hapiMessageConverterHelper;

@Inject Logger logger;

public static HapiResultConverter getInstance() {
return INSTANCE;
}

private HapiResultConverter() {}

@Override
public Result<?> addEtorProcessingTag(final Result<?> message) {
var hapiResult = (Result<Bundle>) message;
var messageBundle = hapiResult.getUnderlyingResult();

hapiMessageConverterHelper.addEtorTagToBundle(messageBundle);

return new HapiResult(messageBundle);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ class ResultMock<T> implements Result<T> {
private String fhirResourceId
private T underlyingResult

ResultMock(String fhirResourceId, T underlyingOrders) {
ResultMock(String fhirResourceId, T underlyingResults) {
this.fhirResourceId = fhirResourceId
this.underlyingResult = underlyingOrders
this.underlyingResult = underlyingResults
}

@Override
Expand Down
Loading
Loading