You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by ma...@apache.org on 2016/10/11 19:01:17 UTC
nifi git commit: Fixed HL7 segment index bug for order control codes,
more testing
Repository: nifi
Updated Branches:
refs/heads/master ee14ae8af -> 6d5f4777c
Fixed HL7 segment index bug for order control codes, more testing
Signed-off-by: Matt Burgess <ma...@apache.org>
Added NOTICE entries for test data and fixed checkstyle violations
Signed-off-by: Matt Burgess <ma...@apache.org>
This closes #1123
Project: http://git-wip-us.apache.org/repos/asf/nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/6d5f4777
Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/6d5f4777
Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/6d5f4777
Branch: refs/heads/master
Commit: 6d5f4777c5ce2e7e361dd0d794d6bdd706222c82
Parents: ee14ae8
Author: Joey Frazee <jo...@icloud.com>
Authored: Tue Oct 11 10:10:43 2016 -0500
Committer: Matt Burgess <ma...@apache.org>
Committed: Tue Oct 11 14:57:40 2016 -0400
----------------------------------------------------------------------
NOTICE | 6 +
.../processors/hl7/ExtractHL7Attributes.java | 26 +-
.../src/main/resources/META-INF/NOTICE | 15 +
.../hl7/TestExtractHL7Attributes.java | 459 +++++++++++++------
4 files changed, 350 insertions(+), 156 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/nifi/blob/6d5f4777/NOTICE
----------------------------------------------------------------------
diff --git a/NOTICE b/NOTICE
index c2026ba..b71bba0 100644
--- a/NOTICE
+++ b/NOTICE
@@ -27,3 +27,9 @@ Copyright 2008-2016 The Apache Software Foundation
The derived work is adapted from
release-1.2.1/ql/src/java/org/apache/hadoop/hive/ql/io/orc/WriterImpl.java
and can be found in the org.apache.hadoop.hive.ql.io.orc package
+
+This includes derived works from the HAPI (MPL 1.1) project (http://hl7api.sourceforge.net/):
+Copyright 2012 University Health Network
+The derived work is adapted from ca.uhn.hapi:hapi-test:2.2 and
+ca.uhn.hapi:hapi-osgi-tests:2.2 and can be found in
+nifi-nar-bundles/nifi-hl7-bundle/nifi-hl7-processors/src/test/java/org/apache/nifi/processors/hl7/TestExtractHL7Attributes.java
http://git-wip-us.apache.org/repos/asf/nifi/blob/6d5f4777/nifi-nar-bundles/nifi-hl7-bundle/nifi-hl7-processors/src/main/java/org/apache/nifi/processors/hl7/ExtractHL7Attributes.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-hl7-bundle/nifi-hl7-processors/src/main/java/org/apache/nifi/processors/hl7/ExtractHL7Attributes.java b/nifi-nar-bundles/nifi-hl7-bundle/nifi-hl7-processors/src/main/java/org/apache/nifi/processors/hl7/ExtractHL7Attributes.java
index ac5b18e..40a7cf9 100644
--- a/nifi-nar-bundles/nifi-hl7-bundle/nifi-hl7-processors/src/main/java/org/apache/nifi/processors/hl7/ExtractHL7Attributes.java
+++ b/nifi-nar-bundles/nifi-hl7-bundle/nifi-hl7-processors/src/main/java/org/apache/nifi/processors/hl7/ExtractHL7Attributes.java
@@ -20,6 +20,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -239,34 +241,32 @@ public class ExtractHL7Attributes extends AbstractProcessor {
private static Map<String, Segment> getAllSegments(final Group group) throws HL7Exception {
final Map<String, Segment> segments = new TreeMap<>();
- addSegments(group, segments);
- return segments;
+ addSegments(group, segments, new HashMap<String, Integer>());
+ return Collections.unmodifiableMap(segments);
}
- private static void addSegments(final Group group, final Map<String, Segment> segments) throws HL7Exception {
+ private static void addSegments(final Group group, final Map<String, Segment> segments, final Map<String, Integer> segmentIndexes) throws HL7Exception {
if (!isEmpty(group)) {
for (final String name : group.getNames()) {
for (final Structure structure : group.getAll(name)) {
if (group.isGroup(name) && structure instanceof Group) {
- addSegments((Group) structure, segments);
+ addSegments((Group) structure, segments, segmentIndexes);
} else if (structure instanceof Segment) {
- addSegments((Segment) structure, segments);
+ addSegments((Segment) structure, segments, segmentIndexes);
}
}
+ segmentIndexes.put(name, segmentIndexes.getOrDefault(name, 1) + 1);
}
}
}
- private static void addSegments(final Segment segment, final Map<String, Segment> segments) throws HL7Exception {
+ private static void addSegments(final Segment segment, final Map<String, Segment> segments, final Map<String, Integer> segmentIndexes) throws HL7Exception {
if (!isEmpty(segment)) {
- final StringBuilder sb = new StringBuilder().append(segment.getName());
+ final String segmentName = segment.getName();
+ final StringBuilder sb = new StringBuilder().append(segmentName);
if (isRepeating(segment)) {
- final Type field = segment.getField(1, 0);
- if (!isEmpty(field)) {
- final String fieldValue = field.encode();
- final int segmentIndex = StringUtils.isEmpty(fieldValue) ? 1 : Integer.parseInt(fieldValue);
- sb.append("_").append(segmentIndex);
- }
+ final int segmentIndex = segmentIndexes.getOrDefault(segmentName, 1);
+ sb.append("_").append(segmentIndex);
}
final String segmentKey = sb.toString();
segments.put(segmentKey, segment);
http://git-wip-us.apache.org/repos/asf/nifi/blob/6d5f4777/nifi-nar-bundles/nifi-hl7-bundle/nifi-hl7-processors/src/main/resources/META-INF/NOTICE
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-hl7-bundle/nifi-hl7-processors/src/main/resources/META-INF/NOTICE b/nifi-nar-bundles/nifi-hl7-bundle/nifi-hl7-processors/src/main/resources/META-INF/NOTICE
new file mode 100644
index 0000000..cae5644
--- /dev/null
+++ b/nifi-nar-bundles/nifi-hl7-bundle/nifi-hl7-processors/src/main/resources/META-INF/NOTICE
@@ -0,0 +1,15 @@
+nifi-hl7-processors
+Copyright 2015-2016 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+*****************
+Mozilla Public License v1.1
+*****************
+
+src/test/java/org/apache/nifi/processors/hl7/TestExtractHL7Attributes.java
+contains test data and examples from HAPI (http://hl7api.sourceforge.net/):
+
+ (MPL 1.1) (ca.uhn.hapi:hapi-test:2.2 - http://hl7api.sourceforge.net/)
+ (MPL 1.1) (ca.uhn.hapi:hapi-osgi-tests:2.2 - http://hl7api.sourceforge.net/)
http://git-wip-us.apache.org/repos/asf/nifi/blob/6d5f4777/nifi-nar-bundles/nifi-hl7-bundle/nifi-hl7-processors/src/test/java/org/apache/nifi/processors/hl7/TestExtractHL7Attributes.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-hl7-bundle/nifi-hl7-processors/src/test/java/org/apache/nifi/processors/hl7/TestExtractHL7Attributes.java b/nifi-nar-bundles/nifi-hl7-bundle/nifi-hl7-processors/src/test/java/org/apache/nifi/processors/hl7/TestExtractHL7Attributes.java
index cec8551..be72017 100644
--- a/nifi-nar-bundles/nifi-hl7-bundle/nifi-hl7-processors/src/test/java/org/apache/nifi/processors/hl7/TestExtractHL7Attributes.java
+++ b/nifi-nar-bundles/nifi-hl7-bundle/nifi-hl7-processors/src/test/java/org/apache/nifi/processors/hl7/TestExtractHL7Attributes.java
@@ -19,7 +19,8 @@ package org.apache.nifi.processors.hl7;
import org.apache.nifi.util.MockFlowFile;
import org.apache.nifi.util.TestRunner;
import org.apache.nifi.util.TestRunners;
-import org.junit.Assert;
+
+import static org.junit.Assert.assertEquals;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -35,18 +36,73 @@ public class TestExtractHL7Attributes {
"MSH|^~\\&|XXXXXXXX||HealthProvider||||ORU^R01|Q1111111111111111111|P|2.3|\r\n" +
"PID|||12345^^^XYZ^MR||SMITH^JOHN||19700100|M||||||||||111111111111|123456789|\r\n" +
"PD1||||1234567890^LAST^FIRST^M^^^^^NPI|\r\n" +
+ "ORC|NW|987654321^EPC|123456789^EPC||||||20161003000000|||SMITH\r\n" +
"OBR|1|341856649^HNAM_ORDERID|000000000000000000|648088^Basic Metabolic Panel|||20150101000000|||||||||1620^Johnson^Corey^A||||||20150101000000|||F|||||||||||20150101000000|\r\n" +
"OBX|1|NM|GLU^Glucose Lvl|59|mg/dL|65-99^65^99|L|||F|||20150102000000|\r\n";
+ private void runTests(final String message, final Map<String, String> expectedAttributes, final boolean useSegmentNames, final boolean parseSegmentFields) {
+ final TestRunner runner = TestRunners.newTestRunner(ExtractHL7Attributes.class);
+ runner.setProperty(ExtractHL7Attributes.USE_SEGMENT_NAMES, String.valueOf(useSegmentNames));
+ runner.setProperty(ExtractHL7Attributes.PARSE_SEGMENT_FIELDS, String.valueOf(parseSegmentFields));
+ runner.enqueue(message.getBytes(StandardCharsets.UTF_8));
+
+ runner.run();
+ runner.assertAllFlowFilesTransferred(ExtractHL7Attributes.REL_SUCCESS, 1);
+
+ final MockFlowFile flowFile = runner.getFlowFilesForRelationship(ExtractHL7Attributes.REL_SUCCESS).get(0);
+
+ final SortedMap<String, String> actualAttributes = new TreeMap<>(flowFile.getAttributes());
+ final SortedMap<String, Integer> actualSegments = new TreeMap<>();
+ final SortedMap<String, Integer> expectedSegments = new TreeMap<>();
+
+ // Get map of actual segment counts
+ for (final Map.Entry<String, String> entry : actualAttributes.entrySet()) {
+ final String key = entry.getKey();
+ if (!(key.equals("filename") || key.equals("path") || key.equals("uuid"))) {
+ final String segment = key.replaceAll("^([^\\.]+)\\.\\d+", "$1");
+ actualSegments.put(segment, actualSegments.getOrDefault(segment, 0) + 1);
+ }
+ }
+
+ // Get map of expected segment counts
+ for (final Map.Entry<String, String> entry : expectedAttributes.entrySet()) {
+ final String key = entry.getKey();
+ final String segment = key.replaceAll("^([^\\.]+)\\.\\d+", "$1");
+ expectedSegments.put(segment, expectedSegments.getOrDefault(segment, 0) + 1);
+ }
+
+ // First, check whether the actual and expected segment counts are the same
+ assertEquals("Segment counts do not match", expectedSegments, actualSegments);
+
+ // Check whether the actual and expected segment field values are the same
+ for (final Map.Entry<String, String> entry : expectedAttributes.entrySet()) {
+ final String key = entry.getKey();
+ final String expected = entry.getValue();
+ final String actual = actualAttributes.get(key);
+ assertEquals(key + " segment value does not match", expected, actual);
+ }
+ }
+
+ private void runTests(final String message, final Map<String, String> expectedAttributes) {
+ runTests(message, expectedAttributes, false, false);
+ }
+
@BeforeClass
public static void setup() {
System.setProperty("org.slf4j.simpleLogger.log.org.apache.nifi", "DEBUG");
}
@Test
- public void testExtract() throws IOException {
+ public void testExtract() {
+ final String message = "MSH|^~\\&|XXXXXXXX||HealthProvider||||ORU^R01|Q1111111111111111111|P|2.3|\r\n" +
+ "PID|||12345^^^XYZ^MR||SMITH^JOHN||19700100|M||||||||||111111111111|123456789|\r\n" +
+ "PD1||||1234567890^LAST^FIRST^M^^^^^NPI|\r\n" +
+ "ORC|NW|987654321^EPC|123456789^EPC||||||20161003000000|||SMITH\r\n" +
+ "OBR|1|341856649^HNAM_ORDERID|000000000000000000|648088^Basic Metabolic Panel|||20150101000000|||||||||1620^Johnson^Corey^A||||||20150101000000|||F|||||||||||20150101000000|\r\n" +
+ "OBX|1|NM|GLU^Glucose Lvl|59|mg/dL|65-99^65^99|L|||F|||20150102000000|\r\n";
+
final SortedMap<String, String> expectedAttributes = new TreeMap<>();
- // MSH.1 and MSH.2 could be escaped, but it's not clear which is right
+
expectedAttributes.put("MSH.1", "|");
expectedAttributes.put("MSH.2", "^~\\&");
expectedAttributes.put("MSH.3", "XXXXXXXX");
@@ -55,6 +111,13 @@ public class TestExtractHL7Attributes {
expectedAttributes.put("MSH.10", "Q1111111111111111111");
expectedAttributes.put("MSH.11", "P");
expectedAttributes.put("MSH.12", "2.3");
+
+ expectedAttributes.put("ORC_1.1", "NW");
+ expectedAttributes.put("ORC_1.2", "987654321^EPC");
+ expectedAttributes.put("ORC_1.3", "123456789^EPC");
+ expectedAttributes.put("ORC_1.9", "20161003000000");
+ expectedAttributes.put("ORC_1.12", "SMITH");
+
expectedAttributes.put("OBR_1.1", "1");
expectedAttributes.put("OBR_1.2", "341856649^HNAM_ORDERID");
expectedAttributes.put("OBR_1.3", "000000000000000000");
@@ -64,6 +127,7 @@ public class TestExtractHL7Attributes {
expectedAttributes.put("OBR_1.22", "20150101000000");
expectedAttributes.put("OBR_1.25", "F");
expectedAttributes.put("OBR_1.36", "20150101000000");
+
expectedAttributes.put("OBX_1.1", "1");
expectedAttributes.put("OBX_1.2", "NM");
expectedAttributes.put("OBX_1.3", "GLU^Glucose Lvl");
@@ -73,7 +137,9 @@ public class TestExtractHL7Attributes {
expectedAttributes.put("OBX_1.7", "L");
expectedAttributes.put("OBX_1.10", "F");
expectedAttributes.put("OBX_1.13", "20150102000000");
+
expectedAttributes.put("PD1.4", "1234567890^LAST^FIRST^M^^^^^NPI");
+
expectedAttributes.put("PID.3", "12345^^^XYZ^MR");
expectedAttributes.put("PID.5", "SMITH^JOHN");
expectedAttributes.put("PID.7", "19700100");
@@ -81,58 +147,20 @@ public class TestExtractHL7Attributes {
expectedAttributes.put("PID.18", "111111111111");
expectedAttributes.put("PID.19", "123456789");
- final TestRunner runner = TestRunners.newTestRunner(ExtractHL7Attributes.class);
- runner.enqueue(TEST_INPUT_RECORD.getBytes(StandardCharsets.UTF_8));
-
- runner.run();
- runner.assertAllFlowFilesTransferred(ExtractHL7Attributes.REL_SUCCESS, 1);
-
- final MockFlowFile out = runner.getFlowFilesForRelationship(ExtractHL7Attributes.REL_SUCCESS).get(0);
- final SortedMap<String, String> sortedAttrs = new TreeMap<>(out.getAttributes());
-
- for (final Map.Entry<String, String> entry : expectedAttributes.entrySet()) {
- final String key = entry.getKey();
- final String expected = entry.getValue();
- final String actual = sortedAttrs.get(key);
- Assert.assertEquals(key + " segment values do not match", expected, actual);
- }
-
- int mshSegmentCount = 0;
- int obrSegmentCount = 0;
- int obxSegmentCount = 0;
- int pd1SegmentCount = 0;
- int pidSegmentCount = 0;
-
- for (final Map.Entry<String, String> entry : sortedAttrs.entrySet()) {
- final String entryKey = entry.getKey();
- if (entryKey.startsWith("MSH")) {
- mshSegmentCount++;
- continue;
- } else if (entryKey.startsWith("OBR")) {
- obrSegmentCount++;
- continue;
- } else if (entryKey.startsWith("OBX")) {
- obxSegmentCount++;
- continue;
- } else if (entryKey.startsWith("PD1")) {
- pd1SegmentCount++;
- continue;
- } else if (entryKey.startsWith("PID")) {
- pidSegmentCount++;
- continue;
- }
- }
-
- Assert.assertEquals("Did not have the proper number of MSH segments", 8, mshSegmentCount);
- Assert.assertEquals("Did not have the proper number of OBR segments", 9, obrSegmentCount);
- Assert.assertEquals("Did not have the proper number of OBX segments", 9, obxSegmentCount);
- Assert.assertEquals("Did not have the proper number of PD1 segments", 1, pd1SegmentCount);
- Assert.assertEquals("Did not have the proper number of PID segments", 6, pidSegmentCount);
+ runTests(message, expectedAttributes);
}
@Test
public void testExtractWithSegmentNames() throws IOException {
+ final String message = "MSH|^~\\&|XXXXXXXX||HealthProvider||||ORU^R01|Q1111111111111111111|P|2.3|\r\n" +
+ "PID|||12345^^^XYZ^MR||SMITH^JOHN||19700100|M||||||||||111111111111|123456789|\r\n" +
+ "PD1||||1234567890^LAST^FIRST^M^^^^^NPI|\r\n" +
+ "ORC|NW|987654321^EPC|123456789^EPC||||||20161003000000|||SMITH\r\n" +
+ "OBR|1|341856649^HNAM_ORDERID|000000000000000000|648088^Basic Metabolic Panel|||20150101000000|||||||||1620^Johnson^Corey^A||||||20150101000000|||F|||||||||||20150101000000|\r\n" +
+ "OBX|1|NM|GLU^Glucose Lvl|59|mg/dL|65-99^65^99|L|||F|||20150102000000|\r\n";
+
final SortedMap<String, String> expectedAttributes = new TreeMap<>();
+
expectedAttributes.put("MSH.FieldSeparator", "|");
expectedAttributes.put("MSH.EncodingCharacters", "^~\\&");
expectedAttributes.put("MSH.SendingApplication", "XXXXXXXX");
@@ -141,6 +169,13 @@ public class TestExtractHL7Attributes {
expectedAttributes.put("MSH.MessageControlID", "Q1111111111111111111");
expectedAttributes.put("MSH.ProcessingID", "P");
expectedAttributes.put("MSH.VersionID", "2.3");
+
+ expectedAttributes.put("ORC_1.OrderControl", "NW");
+ expectedAttributes.put("ORC_1.PlacerOrderNumber", "987654321^EPC");
+ expectedAttributes.put("ORC_1.FillerOrderNumber", "123456789^EPC");
+ expectedAttributes.put("ORC_1.DateTimeOfTransaction", "20161003000000");
+ expectedAttributes.put("ORC_1.OrderingProvider", "SMITH");
+
expectedAttributes.put("OBR_1.SetIDObservationRequest", "1");
expectedAttributes.put("OBR_1.PlacerOrderNumber", "341856649^HNAM_ORDERID");
expectedAttributes.put("OBR_1.FillerOrderNumber", "000000000000000000");
@@ -150,6 +185,7 @@ public class TestExtractHL7Attributes {
expectedAttributes.put("OBR_1.ResultsRptStatusChngDateTime", "20150101000000");
expectedAttributes.put("OBR_1.ResultStatus", "F");
expectedAttributes.put("OBR_1.ScheduledDateTime", "20150101000000");
+
expectedAttributes.put("OBX_1.SetIDOBX", "1");
expectedAttributes.put("OBX_1.ValueType", "NM");
expectedAttributes.put("OBX_1.ObservationIdentifier", "GLU^Glucose Lvl");
@@ -159,7 +195,9 @@ public class TestExtractHL7Attributes {
expectedAttributes.put("OBX_1.ReferencesRange", "L");
expectedAttributes.put("OBX_1.NatureOfAbnormalTest", "F");
expectedAttributes.put("OBX_1.UserDefinedAccessChecks", "20150102000000");
+
expectedAttributes.put("PD1.PatientPrimaryCareProviderNameIDNo", "1234567890^LAST^FIRST^M^^^^^NPI");
+
expectedAttributes.put("PID.PatientIDInternalID", "12345^^^XYZ^MR");
expectedAttributes.put("PID.PatientName", "SMITH^JOHN");
expectedAttributes.put("PID.DateOfBirth", "19700100");
@@ -167,59 +205,20 @@ public class TestExtractHL7Attributes {
expectedAttributes.put("PID.PatientAccountNumber", "111111111111");
expectedAttributes.put("PID.SSNNumberPatient", "123456789");
- final TestRunner runner = TestRunners.newTestRunner(ExtractHL7Attributes.class);
- runner.setProperty(ExtractHL7Attributes.USE_SEGMENT_NAMES, "true");
- runner.enqueue(TEST_INPUT_RECORD.getBytes(StandardCharsets.UTF_8));
-
- runner.run();
- runner.assertAllFlowFilesTransferred(ExtractHL7Attributes.REL_SUCCESS, 1);
-
- final MockFlowFile out = runner.getFlowFilesForRelationship(ExtractHL7Attributes.REL_SUCCESS).get(0);
- final SortedMap<String, String> sortedAttrs = new TreeMap<>(out.getAttributes());
-
- for (final Map.Entry<String, String> entry : expectedAttributes.entrySet()) {
- final String key = entry.getKey();
- final String expected = entry.getValue();
- final String actual = sortedAttrs.get(key);
- Assert.assertEquals(key + " segment values do not match", expected, actual);
- }
-
- int mshSegmentCount = 0;
- int obrSegmentCount = 0;
- int obxSegmentCount = 0;
- int pd1SegmentCount = 0;
- int pidSegmentCount = 0;
-
- for (final Map.Entry<String, String> entry : sortedAttrs.entrySet()) {
- final String entryKey = entry.getKey();
- if (entryKey.startsWith("MSH")) {
- mshSegmentCount++;
- continue;
- } else if (entryKey.startsWith("OBR")) {
- obrSegmentCount++;
- continue;
- } else if (entryKey.startsWith("OBX")) {
- obxSegmentCount++;
- continue;
- } else if (entryKey.startsWith("PD1")) {
- pd1SegmentCount++;
- continue;
- } else if (entryKey.startsWith("PID")) {
- pidSegmentCount++;
- continue;
- }
- }
-
- Assert.assertEquals("Did not have the proper number of MSH segments", 8, mshSegmentCount);
- Assert.assertEquals("Did not have the proper number of OBR segments", 9, obrSegmentCount);
- Assert.assertEquals("Did not have the proper number of OBX segments", 9, obxSegmentCount);
- Assert.assertEquals("Did not have the proper number of PD1 segments", 1, pd1SegmentCount);
- Assert.assertEquals("Did not have the proper number of PID segments", 6, pidSegmentCount);
+ runTests(message, expectedAttributes, true, false);
}
@Test
public void testExtractWithSegmentNamesAndFields() throws IOException {
+ final String message = "MSH|^~\\&|XXXXXXXX||HealthProvider||||ORU^R01|Q1111111111111111111|P|2.3|\r\n" +
+ "PID|||12345^^^XYZ^MR||SMITH^JOHN||19700100|M||||||||||111111111111|123456789|\r\n" +
+ "PD1||||1234567890^LAST^FIRST^M^^^^^NPI|\r\n" +
+ "ORC|NW|987654321^EPC|123456789^EPC||||||20161003000000|||SMITH\r\n" +
+ "OBR|1|341856649^HNAM_ORDERID|000000000000000000|648088^Basic Metabolic Panel|||20150101000000|||||||||1620^Johnson^Corey^A||||||20150101000000|||F|||||||||||20150101000000|\r\n" +
+ "OBX|1|NM|GLU^Glucose Lvl|59|mg/dL|65-99^65^99|L|||F|||20150102000000|\r\n";
+
final SortedMap<String, String> expectedAttributes = new TreeMap<>();
+
expectedAttributes.put("MSH.FieldSeparator", "|");
expectedAttributes.put("MSH.EncodingCharacters", "^~\\&");
expectedAttributes.put("MSH.SendingApplication.HD.1", "XXXXXXXX");
@@ -229,6 +228,15 @@ public class TestExtractHL7Attributes {
expectedAttributes.put("MSH.MessageControlID", "Q1111111111111111111");
expectedAttributes.put("MSH.ProcessingID.PT.1", "P");
expectedAttributes.put("MSH.VersionID", "2.3");
+
+ expectedAttributes.put("ORC_1.OrderControl", "NW");
+ expectedAttributes.put("ORC_1.PlacerOrderNumber.EI.1", "987654321");
+ expectedAttributes.put("ORC_1.PlacerOrderNumber.EI.2", "EPC");
+ expectedAttributes.put("ORC_1.FillerOrderNumber.EI.1", "123456789");
+ expectedAttributes.put("ORC_1.FillerOrderNumber.EI.2", "EPC");
+ expectedAttributes.put("ORC_1.DateTimeOfTransaction", "20161003000000");
+ expectedAttributes.put("ORC_1.OrderingProvider.XCN.1", "SMITH");
+
expectedAttributes.put("OBR_1.SetIDObservationRequest", "1");
expectedAttributes.put("OBR_1.PlacerOrderNumber.EI.1", "341856649");
expectedAttributes.put("OBR_1.PlacerOrderNumber.EI.2", "HNAM_ORDERID");
@@ -243,6 +251,7 @@ public class TestExtractHL7Attributes {
expectedAttributes.put("OBR_1.ResultsRptStatusChngDateTime", "20150101000000");
expectedAttributes.put("OBR_1.ResultStatus", "F");
expectedAttributes.put("OBR_1.ScheduledDateTime", "20150101000000");
+
expectedAttributes.put("OBX_1.SetIDOBX", "1");
expectedAttributes.put("OBX_1.ValueType", "NM");
expectedAttributes.put("OBX_1.ObservationIdentifier.CE.1", "GLU");
@@ -250,16 +259,18 @@ public class TestExtractHL7Attributes {
expectedAttributes.put("OBX_1.ObservationSubID", "59");
expectedAttributes.put("OBX_1.ObservationValue", "mg/dL");
expectedAttributes.put("OBX_1.Units.CE.1", "65-99");
- expectedAttributes.put("OBX_1.Units.CE.3", "65");
+ expectedAttributes.put("OBX_1.Units.CE.2", "65");
expectedAttributes.put("OBX_1.Units.CE.3", "99");
expectedAttributes.put("OBX_1.ReferencesRange", "L");
expectedAttributes.put("OBX_1.NatureOfAbnormalTest", "F");
expectedAttributes.put("OBX_1.UserDefinedAccessChecks", "20150102000000");
+
expectedAttributes.put("PD1.PatientPrimaryCareProviderNameIDNo.XCN.1", "1234567890");
expectedAttributes.put("PD1.PatientPrimaryCareProviderNameIDNo.XCN.2", "LAST");
expectedAttributes.put("PD1.PatientPrimaryCareProviderNameIDNo.XCN.3", "FIRST");
expectedAttributes.put("PD1.PatientPrimaryCareProviderNameIDNo.XCN.4", "M");
expectedAttributes.put("PD1.PatientPrimaryCareProviderNameIDNo.XCN.9", "NPI");
+
expectedAttributes.put("PID.PatientIDInternalID.CX.1", "12345");
expectedAttributes.put("PID.PatientIDInternalID.CX.4", "XYZ");
expectedAttributes.put("PID.PatientIDInternalID.CX.5", "MR");
@@ -270,55 +281,217 @@ public class TestExtractHL7Attributes {
expectedAttributes.put("PID.PatientAccountNumber.CX.1", "111111111111");
expectedAttributes.put("PID.SSNNumberPatient", "123456789");
- final TestRunner runner = TestRunners.newTestRunner(ExtractHL7Attributes.class);
- runner.setProperty(ExtractHL7Attributes.USE_SEGMENT_NAMES, "true");
- runner.setProperty(ExtractHL7Attributes.PARSE_SEGMENT_FIELDS, "true");
- runner.enqueue(TEST_INPUT_RECORD.getBytes(StandardCharsets.UTF_8));
+ runTests(message, expectedAttributes, true, true);
+ }
- runner.run();
- runner.assertAllFlowFilesTransferred(ExtractHL7Attributes.REL_SUCCESS, 1);
+ @Test
+ public void test1714219() {
+ // Message from http://hl7api.sourceforge.net hapi-test/src/test/java/ca/uhn/hl7v2/parser/ParserTest.java
+ final String message = "MSH|^~\\&|Send App|Send Fac|Rec App|Rec Fac|20070504141816||ORM^O01||P|2.2\r" +
+ "PID|||12345678||Lastname^^INI^^PREFIX||19340207|F|||Street 15^^S GRAVENHAGE^^2551HL^NEDERLAND|||||||||||||||NL\r" +
+ "ORC|NW|8100088345^ORDERNR||LN1||C|^^^20070504080000||20070504141816|||0^Doctor\r" +
+ "OBR|1|8100088345^ORDERNR||ADR^Something||||||||||||0^Doctor\r" +
+ "OBX|1|ST|ADR^Something||item1^item2^item3^^item5||||||F\r";
+
+ final SortedMap<String, String> expectedAttributes = new TreeMap<>();
- final MockFlowFile out = runner.getFlowFilesForRelationship(ExtractHL7Attributes.REL_SUCCESS).get(0);
- final SortedMap<String, String> sortedAttrs = new TreeMap<>(out.getAttributes());
+ expectedAttributes.put("MSH.1", "|");
+ expectedAttributes.put("MSH.2", "^~\\&");
+ expectedAttributes.put("MSH.3", "Send App");
+ expectedAttributes.put("MSH.4", "Send Fac");
+ expectedAttributes.put("MSH.5", "Rec App");
+ expectedAttributes.put("MSH.6", "Rec Fac");
+ expectedAttributes.put("MSH.7", "20070504141816");
+ expectedAttributes.put("MSH.9", "ORM^O01");
+ expectedAttributes.put("MSH.11", "P");
+ expectedAttributes.put("MSH.12", "2.2");
- for (final Map.Entry<String, String> entry : expectedAttributes.entrySet()) {
- final String key = entry.getKey();
- final String expected = entry.getValue();
- final String actual = sortedAttrs.get(key);
- Assert.assertEquals(key + " segment values do not match", expected, actual);
- }
+ expectedAttributes.put("PID.3", "12345678");
+ expectedAttributes.put("PID.5", "Lastname^^INI^^PREFIX");
+ expectedAttributes.put("PID.7", "19340207");
+ expectedAttributes.put("PID.8", "F");
+ expectedAttributes.put("PID.11", "Street 15^^S GRAVENHAGE^^2551HL^NEDERLAND");
+ expectedAttributes.put("PID.26", "NL");
- int mshSegmentCount = 0;
- int obrSegmentCount = 0;
- int obxSegmentCount = 0;
- int pd1SegmentCount = 0;
- int pidSegmentCount = 0;
-
- for (final Map.Entry<String, String> entry : sortedAttrs.entrySet()) {
- final String entryKey = entry.getKey();
- if (entryKey.startsWith("MSH")) {
- mshSegmentCount++;
- continue;
- } else if (entryKey.startsWith("OBR")) {
- obrSegmentCount++;
- continue;
- } else if (entryKey.startsWith("OBX")) {
- obxSegmentCount++;
- continue;
- } else if (entryKey.startsWith("PD1")) {
- pd1SegmentCount++;
- continue;
- } else if (entryKey.startsWith("PID")) {
- pidSegmentCount++;
- continue;
- }
- }
+ expectedAttributes.put("ORC_1.1", "NW");
+ expectedAttributes.put("ORC_1.2", "8100088345^ORDERNR");
+ expectedAttributes.put("ORC_1.4", "LN1");
+ expectedAttributes.put("ORC_1.6", "C");
+ expectedAttributes.put("ORC_1.7", "^^^20070504080000");
+ expectedAttributes.put("ORC_1.9", "20070504141816");
+ expectedAttributes.put("ORC_1.12", "0^Doctor");
+
+ expectedAttributes.put("OBR.1", "1");
+ expectedAttributes.put("OBR.2", "8100088345^ORDERNR");
+ expectedAttributes.put("OBR.4", "ADR^Something");
+ expectedAttributes.put("OBR.16", "0^Doctor");
+
+ expectedAttributes.put("OBX.1", "1");
+ expectedAttributes.put("OBX.2", "ST");
+ expectedAttributes.put("OBX.3", "ADR^Something");
+ expectedAttributes.put("OBX.5", "item1^item2^item3^^item5");
+ expectedAttributes.put("OBX.11", "F");
+
+ runTests(message, expectedAttributes);
+ }
+
+ @Test
+ public void testNPACExample() {
+ // Message from http://hl7api.sourceforge.net hapi-osgi-test/src/test/resources/ca/uhn/hl7v2/util/messages.txt
+ final String message = "MSH|^~\\&|RADIS1||DMCRES||1994050216163360||ORU^R01|1994050216163360|D|2.2|964||AL|AL\r" +
+ "MSA|AA|msgCtrlId\r" +
+ "PID|||N00803||RADIOLOGY^INPATIENT^SIX||19520606|F||A||||||||003555||\r" +
+ "PV1||I|N77^7714^01|||||||OB|\r" +
+ "OBR|1|003555.0015.001^DMCRES|0000000566^RADIS1|37953^CT CHEST^L|||199405021545|||||||||||||0000763||||A999|P||||||R/O TUMOR|202300^BAKER^MARK^E|||01^LOCHLEAR, JUDY|\r" +
+ "OBX||TX|FIND^FINDINGS^L|1|This is a test on 05/02/94.|\r" +
+ "OBX||TX|FIND^FINDINGS^L|2|This is a test for the CRR.|\r" +
+ "OBX||TX|FIND^FINDINGS^L|3|This is a test result to generate multiple obr's to check the cost|\r" +
+ "OBX||TX|FIND^FINDINGS^L|4|display for multiple exams.|\r" +
+ "OBX||TX|FIND^FINDINGS^L|5|APPROVING MD:|\r" +
+ "OBR|2|^DMCRES|0000000567^RADIS1|37956^CT ABDOMEN^L|||199405021550|||||||||||||0000763|||||P||||||R/O TUMOR|202300^BAKER^MARK^E|||01^LOCHLEAR, JUDY|\r" +
+ "OBR|3|^DMCRES|0000000568^RADIS1|37881^CT PELVIS (LIMITED)^L|||199405021551|||||||||||||0000763|||||P||||||R/O TUMOR|202300^BAKER^MARK^E|||01^LOCHLEAR, JUDY|";
- Assert.assertEquals("Did not have the proper number of MSH segments", 9, mshSegmentCount);
- Assert.assertEquals("Did not have the proper number of OBR segments", 14, obrSegmentCount);
- Assert.assertEquals("Did not have the proper number of OBX segments", 12, obxSegmentCount);
- Assert.assertEquals("Did not have the proper number of PD1 segments", 5, pd1SegmentCount);
- Assert.assertEquals("Did not have the proper number of PID segments", 9, pidSegmentCount);
+ final SortedMap<String, String> expectedAttributes = new TreeMap<>();
+
+ expectedAttributes.put("MSH.1", "|");
+ expectedAttributes.put("MSH.2", "^~\\&");
+ expectedAttributes.put("MSH.3", "RADIS1");
+ expectedAttributes.put("MSH.5", "DMCRES");
+ expectedAttributes.put("MSH.7", "1994050216163360");
+ expectedAttributes.put("MSH.9", "ORU^R01");
+ expectedAttributes.put("MSH.10", "1994050216163360");
+ expectedAttributes.put("MSH.11", "D");
+ expectedAttributes.put("MSH.12", "2.2");
+ expectedAttributes.put("MSH.13", "964");
+ expectedAttributes.put("MSH.15", "AL");
+ expectedAttributes.put("MSH.16", "AL");
+
+ expectedAttributes.put("MSA.1", "AA");
+ expectedAttributes.put("MSA.2", "msgCtrlId");
+
+ expectedAttributes.put("PID.3", "N00803");
+ expectedAttributes.put("PID.5", "RADIOLOGY^INPATIENT^SIX");
+ expectedAttributes.put("PID.7", "19520606");
+ expectedAttributes.put("PID.8", "F");
+ expectedAttributes.put("PID.10", "A");
+ expectedAttributes.put("PID.18", "003555");
+
+ expectedAttributes.put("PV1.2", "I");
+ expectedAttributes.put("PV1.3", "N77^7714^01");
+ expectedAttributes.put("PV1.10", "OB");
+
+ expectedAttributes.put("OBR_1.1", "1");
+ expectedAttributes.put("OBR_1.2", "003555.0015.001^DMCRES");
+ expectedAttributes.put("OBR_1.3", "0000000566^RADIS1");
+ expectedAttributes.put("OBR_1.4", "37953^CT CHEST^L");
+ expectedAttributes.put("OBR_1.7", "199405021545");
+ expectedAttributes.put("OBR_1.20", "0000763");
+ expectedAttributes.put("OBR_1.24", "A999");
+ expectedAttributes.put("OBR_1.25", "P");
+ expectedAttributes.put("OBR_1.31", "R/O TUMOR");
+ expectedAttributes.put("OBR_1.32", "202300^BAKER^MARK^E");
+ expectedAttributes.put("OBR_1.35", "01^LOCHLEAR, JUDY");
+
+ expectedAttributes.put("OBX_1.2", "TX");
+ expectedAttributes.put("OBX_1.3", "FIND^FINDINGS^L");
+ expectedAttributes.put("OBX_1.4", "1");
+ expectedAttributes.put("OBX_1.5", "This is a test on 05/02/94.");
+
+ expectedAttributes.put("OBX_2.2", "TX");
+ expectedAttributes.put("OBX_2.3", "FIND^FINDINGS^L");
+ expectedAttributes.put("OBX_2.4", "2");
+ expectedAttributes.put("OBX_2.5", "This is a test for the CRR.");
+
+ expectedAttributes.put("OBX_3.2", "TX");
+ expectedAttributes.put("OBX_3.3", "FIND^FINDINGS^L");
+ expectedAttributes.put("OBX_3.4", "3");
+ expectedAttributes.put("OBX_3.5", "This is a test result to generate multiple obr's to check the cost");
+
+ expectedAttributes.put("OBX_4.2", "TX");
+ expectedAttributes.put("OBX_4.3", "FIND^FINDINGS^L");
+ expectedAttributes.put("OBX_4.4", "4");
+ expectedAttributes.put("OBX_4.5", "display for multiple exams.");
+
+ expectedAttributes.put("OBX_5.2", "TX");
+ expectedAttributes.put("OBX_5.3", "FIND^FINDINGS^L");
+ expectedAttributes.put("OBX_5.4", "5");
+ expectedAttributes.put("OBX_5.5", "APPROVING MD:");
+
+ expectedAttributes.put("OBR_2.1", "2");
+ expectedAttributes.put("OBR_2.2", "^DMCRES");
+ expectedAttributes.put("OBR_2.3", "0000000567^RADIS1");
+ expectedAttributes.put("OBR_2.4", "37956^CT ABDOMEN^L");
+ expectedAttributes.put("OBR_2.7", "199405021550");
+ expectedAttributes.put("OBR_2.20", "0000763");
+ expectedAttributes.put("OBR_2.25", "P");
+ expectedAttributes.put("OBR_2.31", "R/O TUMOR");
+ expectedAttributes.put("OBR_2.32", "202300^BAKER^MARK^E");
+ expectedAttributes.put("OBR_2.35", "01^LOCHLEAR, JUDY");
+
+ expectedAttributes.put("OBR_3.1", "3");
+ expectedAttributes.put("OBR_3.2", "^DMCRES");
+ expectedAttributes.put("OBR_3.3", "0000000568^RADIS1");
+ expectedAttributes.put("OBR_3.4", "37881^CT PELVIS (LIMITED)^L");
+ expectedAttributes.put("OBR_3.7", "199405021551");
+ expectedAttributes.put("OBR_3.20", "0000763");
+ expectedAttributes.put("OBR_3.25", "P");
+ expectedAttributes.put("OBR_3.31", "R/O TUMOR");
+ expectedAttributes.put("OBR_3.32", "202300^BAKER^MARK^E");
+ expectedAttributes.put("OBR_3.35", "01^LOCHLEAR, JUDY");
+
+ runTests(message, expectedAttributes);
}
+ @Test
+ public void testADT() {
+ // Message from http://hl7api.sourceforge.net hapi-osgi-test/src/test/resources/ca/uhn/hl7v2/parser/tests/adt_a03.txt
+ final String message = "MSH|^~\\&|IRIS|SANTER|AMB_R|SANTER|200803051508||ADT^A03|263206|P|2.5\r" +
+ "EVN||200803051509||||200803031508\r" +
+ "PID|||5520255^^^PK^PK~ZZZZZZ83M64Z148R^^^CF^CF~ZZZZZZ83M64Z148R^^^SSN^SSN^^20070103^99991231~^^^^TEAM||ZZZ^ZZZ||19830824|F||||||||||||||||||||||N\r" +
+ "PV1||I|6402DH^^^^^^^^MED. 1 - ONCOLOGIA^^OSPEDALE MAGGIORE DI LODI&LODI|||^^^^^^^^^^OSPEDALE MAGGIORE DI LODI&LODI|13936^TEST^TEST" +
+ "||||||||||5068^TEST2^TEST2||2008003369||||||||||||||||||||||||||200803031508\r" +
+ "PR1|1||1111^Mastoplastica|Protesi|20090224|02|";
+
+ final SortedMap<String, String> expectedAttributes = new TreeMap<>();
+
+ expectedAttributes.put("MSH.1", "|");
+ expectedAttributes.put("MSH.2", "^~\\&");
+ expectedAttributes.put("MSH.3", "IRIS");
+ expectedAttributes.put("MSH.4", "SANTER");
+ expectedAttributes.put("MSH.5", "AMB_R");
+ expectedAttributes.put("MSH.6", "SANTER");
+ expectedAttributes.put("MSH.7", "200803051508");
+ expectedAttributes.put("MSH.9", "ADT^A03");
+ expectedAttributes.put("MSH.10", "263206");
+ expectedAttributes.put("MSH.11", "P");
+ expectedAttributes.put("MSH.12", "2.5");
+
+ expectedAttributes.put("EVN.2", "200803051509");
+ expectedAttributes.put("EVN.6", "200803031508");
+
+ // NOTE: PID.3 should be the following but there's a long-standing bug where additional fields don't get rendered here
+ //expectedAttributes.put("PID.3", "5520255^^^PK^PK~ZZZZZZ83M64Z148R^^^CF^CF~ZZZZZZ83M64Z148R^^^SSN^SSN^^20070103^99991231~^^^^TEAM");
+
+ expectedAttributes.put("PID.3", "5520255^^^PK^PK");
+ expectedAttributes.put("PID.5", "ZZZ^ZZZ");
+ expectedAttributes.put("PID.7", "19830824");
+ expectedAttributes.put("PID.8", "F");
+ expectedAttributes.put("PID.30", "N");
+
+ expectedAttributes.put("PV1.2", "I");
+ expectedAttributes.put("PV1.3", "6402DH^^^^^^^^MED. 1 - ONCOLOGIA^^OSPEDALE MAGGIORE DI LODI&LODI");
+ expectedAttributes.put("PV1.6", "^^^^^^^^^^OSPEDALE MAGGIORE DI LODI&LODI");
+ expectedAttributes.put("PV1.7", "13936^TEST^TEST");
+ expectedAttributes.put("PV1.17", "5068^TEST2^TEST2");
+ expectedAttributes.put("PV1.19", "2008003369");
+ expectedAttributes.put("PV1.45", "200803031508");
+
+ expectedAttributes.put("PR1_1.1", "1");
+ expectedAttributes.put("PR1_1.3", "1111^Mastoplastica");
+ expectedAttributes.put("PR1_1.4", "Protesi");
+ expectedAttributes.put("PR1_1.5", "20090224");
+ expectedAttributes.put("PR1_1.6", "02");
+
+ runTests(message, expectedAttributes);
+ }
}