In the BizTalk HL7 accelerator, you set up the port definition and assign the delimiters in HEX, but then if you are going to test it using the MLLP Send test tool, you have to use the Decimal equivalent. I am surprised that they did not include the following table as part of the documentation.

Also, one of the things not clearly explained is the promoted property DoorbellFinalMessage(BTAHL7Schemas.MSH1) = 124; this is the decimal version of |

   
DOS
Port
Char/Description
0
00
null
1
01
start of heading
2
02
start of text
3
03
end of text
4
04
end of transmission
5
05
enquiry
6
06
acknowledge
7
07
bell
8
08
backspace
9
09
horizontal tab
10
0A
new line
11
0B
vertical tab
12
0C
new page
13
0D
carriage return
14
0E
shift out
15
0F
shift in
16
10
data link escape
17
11
device control 1
18
12
device control 2
19
13
device control 3
20
14
device control 4
21
15
negative acknowledge
22
16
synchronous idle
23
17
end of trans. block
24
18
cancel
25
19
end of medium
26
1A
substitute
27
1B
escape
28
1C
file separator
29
1D
group separator
30
1E
record separator
31
1F
unit separator
32
20
space
33
21
!
34
22

35
23
#
36
24
$
37
25
%
38
26
&
39
27

40
28
(
41
29
)
42
2A
*
43
2B
+
44
2C
,
45
2D
-
46
2E
.
47
2F
/
48
30
0
49
31
1
50
32
2
51
33
3
52
34
4
53
35
5
54
36
6
55
37
7
56
38
8
57
39
9
58
3A
:
59
3B
;
60
3C
<
61
3D
=
62
3E
>
63
3F
?
64
40
@
65
41
A
66
42
B
67
43
C
68
44
D
69
45
E
70
46
F
71
47
G
72
48
H
73
49
I
74
4A
J
75
4B
K
76
4C
L
77
4D
M
78
4E
N
79
4F
O
80
50
P
81
51
Q
82
52
R
83
53
S
84
54
T
85
55
U
86
56
V
87
57
W
88
58
X
89
59
Y
90
5A
Z
91
5B
[
92
5C

93
5D
]
94
5E
^
95
5F
_
96
60
`
97
61
a
98
62
b
99
63
c
100
64
d
101
65
e
102
66
f
103
67
g
104
68
h
105
69
i
106
6A
j
107
6B
k
108
6C
l
109
6D
m
110
6E
n
111
6F
o
112
70
p
113
71
q
114
72
r
115
73
s
116
74
t
117
75
u
118
76
v
119
77
w
120
78
x
121
79
y
122
7A
z
123
7B
{
124
7C
|
125
7D
}
126
7E
~
127
7F
DEL
 

It seems that every client that I assist in implementing HL7, we get to testing the process and we send in an ADT, ORM, ORU, or some other message and we wait for the automated acknowledment, but it never comes.

I then remember that unless I have MLLP version 1.0.308.0, and 1.0.309.0 (current) of Microsoft.solutions.btahl7.mllp.dll I better camp out for a while, while I know it states that it can take up to 10 seconds to get the ack, I have gone to lunch and come back with no response. I even heard that there is a 24 hr delay. So make sure that you have the following patches from Microsoft for the HL7 adapter.

  • KB893369: HL7 Interrogative transactions may take 10 or more seconds to complete when MLLP synchronizes communications end-to-end
  • KB893404: The BizTalk Accelerator for HL7 sends an acknowledgement message to the source system after a long delay

Don’t forget to follow the post installation instruction on getting the send adapter to be a solicit/response as documented here.

 

One little documented behavior of the MLLP adapter is that it is a streaming adapter. The implications are that if you are developing custom pipeline components, you need to make sure that you stay away from reading the Length of the Stream. What should be done is your pipeline component should read the stream completely before doing it’s ‘work.’ (Loop till Read method returns 0).

I have included this VB and this C# example to look at.

I want to thank support for this bit of info!

 

I had forgot that a while ago, I had to create a custom HL7 message, and I saw a question on the forum asking how you can do it.

Here are the steps: (All modifications take place in both the MSH_231_GLO_DEF and the tablevalues.xsd). In this example I am creating a ZZZ^Z01 message;

  1. Edit Table76 and add the message type (add an enumeration) by editing the schema in a text editor:(in my case ZZZ)
     TableValues76
  2. Edit Table3 to represent the trigger:(in my case Z01)
     TableValues3
  3. Edit the MSH 9.0 Sub Element
     MSH9.0
  4. Edit the MSH 9.1 Sub Element
    MSH9.1
  5. Finally create your schema with the root node that follows the following algorithm: Body schema type = TargetNS + “#” + MSH9.1 + MSH9.2 + MSH12.1 (with dots removed) + MSH12.2 (or GLO if the value is blank) + MSH12.3 (or DEF if the value is blank), and don’t forget to make sure that the target namespace of the schema matches what you have defined in the BTAHL7 Configuration Explorer
    ZZZZ01Schema

Some things to make note of:

  • If you are making this new message for a target namespace not the default, the MSH schema that comes needs to be modified. The BTAHL7 pipeline will only look for the default one that comes installed.
  • Make sure that the message that is coming in has the EVN.1 code that matches the MSH.9
 

I am not sure if you are as lazy as I am, but I have really gotten tired of typing all of the command line parameters to test a file using the MLLP adapter.
I finally got off my lazy arse, and created a shortcut.
1. I went into the enviornment properties of My Computer and added the {path}HL7SDKUtilities to the Path, so I did not have to specify the path to the mllpsend.exe
2. I created a batch file (submit.cmd) that is simply two lines:
mllpsend /SB 11 /EB 28 /CR 13 /twoway /f %1
pause
3. I then went to Tool -> Folder Options -> File Types and found .TXT files and clicked on Advanced
4. Added an item called mllpsend and the application used to perform is “{path}submit.cmd” “%1″

Now every time I right click a .txt file I have the ability to send it to the MLLP adapter.

Hope that this helps you as much as it does me!

 

This is a gotcha that is hard to figure out, especially if you are trying to install and don’t have the documentation in front of you, because it is trying to install it!

In the documentation, it states:

Log on using an account that is a member of the BizTalk Server Administrators group.

Note  This user account must also be a member of the Administrators group on the SQL Server in which you will store BTAHL7 data.

This is normally an issue when you install it and it states: ‘The Specified account “###/###” is
invalid. Error code: Logon Failure: unknown user name or bad password.’

 

A recent post was asking how to set up a two-way port with an orchestration to create acknowledgements.

  • What we did is in the configuration tool, we set the properties for the MSH 3.1 to the following:
    mllp config
    so that the pipeline component will only auto generate a NAK in case of a bad message.
  • We did not want a CA generated stated that we got the message (with or without data errors), we just wanted to know if it was valid or not, hence MSH15=NE.
  • The MSH 16=ER, we only wanted it to create an NAK if there were errors.
  • Then in the orchestration we have a filter only looking for BTAHL7Schemas.ParseError==false (so only good HL7 messages trigger the orchestration).
  • Then in the orchestration we create our positive ACK (setting MSA 2 to AA) and send it back; completing our two-way port in the orchestration.
  • We also have a Dump send port that is filtered on BTAHL7Schemas.ParseError==true and the pipeline is set to DefaultPipelines.PassThruTransmit (since the HL7 DASM could not successfully parse it, it still resides in its text blob form), where the original HL7 message could be looked at futher for troubleshooting purposes and not have a suspended message in the message box.
  • We also promoted the MSA 2 and created a filter where we could capture the autogenerated NAK (MSA_2!=”AA”). This allowed us to look at both the bad message and a copy of the NAK that was sent back to the originating system.

This fulfills our requirements to send back an ack, but then the ack gets generated either by the pipeline component (NAK) or by our orchestration (ACK).

I want to thank my friends in Portugal for encouraging me to clarify this blog entry.

 

I can’t remember how many times I have read entries posted on the various forums asking how to get looping correct in the HL7 messages. A couple of friends have asked how I have done it, so I thought that I would post how you do it.

The real issue is that the looping does not follow the necessary structure defined in the HL7 schemas. The source records in many cases need to match with sequence group (which is not possible in the BizTalk mapper). In the following example, after mapping out some sample data, I manually ran the map, and this is the result I received for the ORU_R01:
mappersample.JPG
but this will not work, because OBR 4.1 does not repeat and will cause the BTAHL7 ASM will throw errors, for this and a LOT of other non-conforming message structures.

In the mapper, what I really need is highlighted in RED:

Fake Mapping
So I reverted to XSLT to do what I needed to be done. I did all of the mapping, afterwards, I right clicked the map and chose Validate Map, and opened up the TestMap_xslt.xml in a text editor.

I then edited the xslt and moved around/deleted the xsl:for-each select=”Order” tags, and also some of the tags. I then saved the document as XSLTMap.xslt.I created a new map (XSLTMap.btm), defined the input schema and the output schema, clicked on the grid and chose Custom XSLT Path and browsed to the xslt file I just created (XSLTMap.xslt). I then tested it against the xml document and made sure that it looked correct.

In the orchestration I created a construct shape, and created 3 maps that defined all three message parts (compared to how the tutorial works, as I don’t really like to hard code stuff in a message assignment shape). I did have to assign some context properties in a message assignment shape, and then sent it off.

I ended up getting the following error:
Alternate Error Number: 301
Alternate Error Description: XmlReader not positioned at root elment of ‘ORU_R01_231_GLO_DEF’
Alternate Encoding System: HL7-BTA

The issue ended up being that in my custom xslt, there is the following tag: omit-xml-declaration=”no”

This caused the BodySegments message part to look like this at the beginning of the message:
xmlheader.JPG
So in the xslt, it is necessary to make sure that the omit-xml-declaration=”yes”

Here is the example (BizTalk 2004) that transforms the following XML message:
Original XML

And transforms it in the correct repeating structure to:

MSH|^~&|Sender||Receiver||||ORU^R01|1234567|D|2.3.1
OBR||||^ServiceID_1
NTE|||Note_1
OBX||AD|^Text_1||||||||C
NTE|||Comment_1~Comment_2
OBX||CE|^Text_2||||||||D
NTE|||Comment_3~Comment_4
OBX||CF|^Text_3||||||||F
NTE|||Comment_5~Comment_6
OBX||CK|^Text_4||||||||I
NTE|||Comment_7
CTI|^^Id_1
OBR||||^ServiceID_2
NTE|||Note_2
OBX||CN|^Text_5||||||||N
NTE|||Comment_8~Comment_9
OBX||CP|^Text_6||||||||O
NTE|||Comment_10
CTI|^^Id_2

So in order to keep the correct looping, you need to be a little XSLT savy, but after playing with it for a little bit, you should be able to get your output correct.

The solution has the initial mapping called TestMap.btm, the results of that map:HL7Msg_MisAlligned_BodySegments.xml, the final map: XSLTMap.btm, the trigger xml:Data.xml, along with the 2XCommon and 231Common projects.

I checked with some friends at Microsoft to confirm that this is the only solution for the looping dilemma but it looks like there is light at the end of the tunnel (I will post the official documentation as soon as I know):

“This is a known issue in the BizTalk mapper which impacts mapping HL7 v2.x schemas.

I’m happy to report some good news on this.  A DCR, to allow the BizTalk mapper to preserve order for repeating segments in the XSLT generation process, has been accepted this week to be included in BizTalk Server 2006 R2.  In the meantime, we are documenting a process that requires generating an XSLT with the BizTalk mapper, then manually inserting a loop in the XSLT around the nodes in the sequence where the order needs to be preserved. “

 

A friend emailed me asking why he was getting a <0d><0a> in his HL7 data when he defined in his Send Port, the following:
Port Properties
You would expect that the data would be:

MSHSegment<0d>PIDSegment<0d>…

But he was getting

MSHSegment<0d><0a>PIDSegment<0d><0a>…

In the message assignment of the multi-part message before you send the data out, if you want only <0d> and not <0d><0a>, you need to set the following context property to false. In the tutorials, you are instructed to put true.

OutgoingMsg(BTAHL7Schemas.SegmentDelimiter2Char)=false;

Although I already mentioned it, OutgoingMsg(BTAHL7Schemas.MSH1)=124; is the decimal value of the | character

 

In an effort to expand on this entry, while testing, there are many times where I have to use the mllpreceive.exe to capture data.

I have made it easy by adding right click functionality.

I created a batch file called Receive.bat with the following contents:

MLLPRECEIVE.EXE /P 12000 /SPLIT /SB 11 /EB 28 /CR 13 /D %1

I then went into Tools -> folder options and choose File Types and chose Folder (not File Folder) and choose Advanced. In the Action I put mllp and the Application used to perform this action I type “{path}Receive.bat” “%1″

Now when I want to receive message and put them in a particuar folder, I right click on the folder, choose mllp from within Explorer, and a dos window comes up with the correct folder that will be the location of where the data will be written to.

© 2012 HL7 and BizTalk Blog Suffusion theme by Sayontan Sinha