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

Refactor HapiHL7Message.getName to return more useful identifier #1636

Merged
merged 6 commits into from
Dec 3, 2024

Conversation

basiliskus
Copy link
Contributor

@basiliskus basiliskus commented Dec 2, 2024

Description

This PR removes HapiHL7Message.getName method and adds HapiHL7Message.getIdentifier which returns MSH-10 that identifies the message. Using this value we can now identify which test message failed for a specific rule in the Automated Test failure logs

Before:
Assertion failed for rule (ORU)

After:
Assertion failed for rule (009)

There is also some refactoring to better isolate the Hapi HL7 library using the HapiHL7Message wrapper and HealthData interface

Issue

#1621

Copy link

github-actions bot commented Dec 2, 2024

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

🎫 Ticket compliance analysis 🔶

1621 - Partially compliant

Fully compliant requirements:

  • Refactor HapiHL7Message.getName to return more useful name

Not compliant requirements:

  • The identifier name could be the file name, MSH-10 or something else
  • Use a name that can be used to log a message that had an issue
⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Possible Bug
The refactoring changes the method signature and behavior which might affect existing functionalities that depend on the old method.

Copy link

github-actions bot commented Dec 2, 2024

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Score
Possible issue
Add null check for msh10 before using it as a key to prevent NullPointerException

Ensure that the parseAndMapMessageByControlId method handles potential
NullPointerException when msh10 is null before using it as a key in messageMap.

rs-e2e/src/main/java/gov/hhs/cdc/trustedintermediary/rse2e/external/hapi/HapiHL7FileMatcher.java [72-76]

 if (msh10 == null || msh10.isEmpty()) {
     throw new HapiHL7FileMatcherException(
             String.format("MSH-10 is empty for file: %s", fileName));
+} else {
+    messageMap.put(msh10, hapiHL7Message);
 }
-messageMap.put(msh10, hapiHL7Message);
Suggestion importance[1-10]: 8

Why: This suggestion correctly identifies a potential NullPointerException due to the use of msh10 as a key in a map without ensuring it's not null. Implementing this check enhances the robustness and reliability of the code.

8
Add null check for mshSegment to prevent NullPointerException

Handle the potential NullPointerException that could occur if mshSegment is null
after attempting to retrieve it from underlyingData.

rs-e2e/src/main/java/gov/hhs/cdc/trustedintermediary/rse2e/external/hapi/HapiHL7Message.java [32-33]

 MSH mshSegment = (MSH) underlyingData.get("MSH");
-return mshSegment.getMessageControlID().getValue();
+if (mshSegment != null) {
+    return mshSegment.getMessageControlID().getValue();
+} else {
+    return null;
+}
Suggestion importance[1-10]: 8

Why: The suggestion is valid as it addresses a potential NullPointerException when mshSegment could be null. This check ensures the stability of the method by preventing runtime exceptions.

8
Add exception handling for IOException during byte reading to enhance robustness

Ensure that the parseAndMapMessageByControlId method properly handles IOException
that might be thrown when reading bytes from the InputStream.

rs-e2e/src/main/java/gov/hhs/cdc/trustedintermediary/rse2e/external/hapi/HapiHL7FileMatcher.java [68-69]

-String content = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
+String content;
+try {
+    content = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
+} catch (IOException e) {
+    throw new HapiHL7FileMatcherException(
+            String.format("Failed to read bytes from file: %s", fileName), e);
+}
 Message message = parser.parse(content);
Suggestion importance[1-10]: 7

Why: This suggestion is relevant as it adds necessary exception handling for IOException which could occur during byte reading from an InputStream. This improvement ensures that the method can gracefully handle I/O errors.

7
Add duplicate key check to prevent data overwrites in the map

Validate that the parseAndMapMessageByControlId method correctly handles cases where
msh10 might be duplicated across multiple files, potentially causing data overwrite
in messageMap.

rs-e2e/src/main/java/gov/hhs/cdc/trustedintermediary/rse2e/external/hapi/HapiHL7FileMatcher.java [76]

-messageMap.put(msh10, hapiHL7Message);
+if (messageMap.containsKey(msh10)) {
+    throw new HapiHL7FileMatcherException(
+            String.format("Duplicate MSH-10 identifier found for file: %s", fileName));
+} else {
+    messageMap.put(msh10, hapiHL7Message);
+}
Suggestion importance[1-10]: 7

Why: The suggestion to check for duplicate msh10 values before putting them in the map is crucial to avoid data integrity issues. This check prevents overwriting existing entries, which could lead to data loss or incorrect data processing.

7

@basiliskus basiliskus marked this pull request as ready for review December 3, 2024 20:25
@basiliskus basiliskus changed the title Refactor HapiHL7Message.getName to return more useful name Refactor HapiHL7Message.getName to return more useful identifier Dec 3, 2024
@@ -35,8 +35,8 @@ class HapiHL7FileMatcherTest extends Specification {
def mockInputMessage2 = Mock(Message)
def mockOutputMessage1 = Mock(Message)
def mockOutputMessage2 = Mock(Message)
spyFileMatcher.mapMessageByControlId(mockInputFiles) >> [ "001": mockInputMessage1, "002": mockInputMessage2 ]
spyFileMatcher.mapMessageByControlId(mockOutputFiles) >> [ "001": mockOutputMessage1, "002": mockOutputMessage2 ]
spyFileMatcher.parseAndMapMessageByControlId(mockInputFiles) >> ["001": mockInputMessage1, "002": mockInputMessage2 ]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't parseAndMapMessageByControlId now returning a map of string to HapiHL7Message now? This test here, and below, are still returning a map of a string to Message. Shouldn't this be updated?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. I'll update it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link

sonarqubecloud bot commented Dec 3, 2024

Copy link
Member

@halprin halprin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good.

@basiliskus basiliskus merged commit 1a34f32 into main Dec 3, 2024
18 checks passed
@basiliskus basiliskus deleted the story/1621/refactor-getname branch December 3, 2024 21:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants