<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>thread dump &#187; HL7</title>
	<atom:link href="http://roger.searjeant.net/wp/category/hl7/feed/" rel="self" type="application/rss+xml" />
	<link>http://roger.searjeant.net/wp</link>
	<description></description>
	<lastBuildDate>Wed, 11 Nov 2009 20:35:00 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>OpenESB and BPEL</title>
		<link>http://roger.searjeant.net/wp/2009/03/openesb-and-bpel/</link>
		<comments>http://roger.searjeant.net/wp/2009/03/openesb-and-bpel/#comments</comments>
		<pubDate>Fri, 27 Mar 2009 19:21:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[HL7]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[NetBeans]]></category>
		<category><![CDATA[OpenESB]]></category>

		<guid isPermaLink="false">http://roger.searjeant.net/wp/2009/03/openesb-and-bpel/</guid>
		<description><![CDATA[Thanks to the folks who commented on yesterday’s post I have managed to overcome the assign problem and of course the answer was very simple: I had an inconsistent set of components installed in NetBeans and GlassFish.&#160; I was using NB 6.5 together with components downloaded from the OpenESB site.&#160; 
The best solution is simply [...]]]></description>
			<content:encoded><![CDATA[<p>Thanks to the folks who commented on yesterday’s post I have managed to overcome the assign problem and of course the answer was very simple: I had an inconsistent set of components installed in <a href="http://www.netbeans.org/">NetBeans</a> and <a href="https://glassfish.dev.java.net/">GlassFish</a>.&#160; I was using NB 6.5 together with components downloaded from the <a href="https://open-esb.dev.java.net/">OpenESB</a> site.&#160; </p>
<p>The best solution is simply to download the complete NetBeans/GlassFish/OpenESB combination from the <a href="https://open-esb.dev.java.net/Downloads.html">OpenESB downloads page</a> and work with that. On the download page the top section contains the GA (stable) GlassFish ESB / NetBeans combination, and the nightly build of the latest (unstable) additional components (i.e. binding components, service engines etc.) which match this GA release.</p>
<p>The next major section on the page contains the GlassFish ESB v2.1 downloads (milestone 1 at the time of writing), which are not yet considered stable. I grabbed the 2.1 release, plus the HL7 BC (and NB design-time modules) from here.&#160; Installation was completely pain-free.&#160; I particularly liked the way the additional components are packaged as a jar-based installer – very nicely done.&#160; </p>
<p>Because the main package is a GlassFish ESB bundle, it installs by default to a non-standard path: C:\GlassFishESB. Everything is installed under this directory, including the configuration files for NetBeans, which would normally be placed in your home directory (under .netbeans). Presumably this is done to allow parallel installation with a stable NetBeans/GF without either interfering with the other. What this means, of course, is that all your preferences (editor settings etc.) are not transferred. This is easily fixed, manually, by copying over the stuff from: C:\Documents and Settings\&lt;user&gt;\.netbeans\6.5\config\Editors to C:\GlassFishESB\.netbeans\glassfishesb\config\Editors</p>
<p>Anyway, back to the BPEL issue.&#160; A clean rebuild of everything was sufficient: the CA deployed to GF, and it ran fine.&#160; I used Hermes JMS and watched the test messages arrive on the queue. Now I can push ahead and explore more of OpenESB and BPEL.</p>
<div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:48af7feb-553d-417c-a460-8b0846fa0e32" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati Tags: <a href="http://technorati.com/tags/OpenESB" rel="tag">OpenESB</a>,<a href="http://technorati.com/tags/NetBeans" rel="tag">NetBeans</a>,<a href="http://technorati.com/tags/BPEL" rel="tag">BPEL</a>,<a href="http://technorati.com/tags/Java" rel="tag">Java</a></div>
]]></content:encoded>
			<wfw:commentRss>http://roger.searjeant.net/wp/2009/03/openesb-and-bpel/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Problem with OpenESB BPEL assign</title>
		<link>http://roger.searjeant.net/wp/2009/03/problem-with-openesb-bpel-assign/</link>
		<comments>http://roger.searjeant.net/wp/2009/03/problem-with-openesb-bpel-assign/#comments</comments>
		<pubDate>Thu, 26 Mar 2009 22:41:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[HL7]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[NetBeans]]></category>
		<category><![CDATA[OpenESB]]></category>

		<guid isPermaLink="false">http://roger.searjeant.net/wp/2009/03/problem-with-openesb-bpel-assign/</guid>
		<description><![CDATA[After far too many cycles staring at code, building, deploying, debugging and undeploying a pretty simple composite application, the damn BPEL assign activity still causes selectionFailure at runtime.
The BPEL is trivial, and the BPEL copy elements for optional elements in the source schema are marked with the ignoreMissingFromData attribute.&#160; I have rebuilt everything from scratch.&#160; [...]]]></description>
			<content:encoded><![CDATA[<p>After far too many cycles staring at code, building, deploying, debugging and undeploying a pretty simple composite application, the damn BPEL assign activity still causes selectionFailure at runtime.</p>
<p>The BPEL is trivial, and the BPEL copy elements for optional elements in the source schema are marked with the ignoreMissingFromData attribute.&#160; I have rebuilt everything from scratch.&#160; I know the redeployments are successful because the error reports points to the correct line following an edit and I can use the BPEL debugger to step through the assign, eventually failing on the optional element.</p>
<p>I was given the hint about the ignoreMissingFromData attribute by Michael Czapski, in a <a href="http://blogs.sun.com/javacapsfieldtech/entry/hl7_processor_demonstration_java_caps">blog comment</a>.&#160; Googling around for more help, I came across a few <a href="http://n2.nabble.com/&quot;ignoreMissingFromData&quot;,-usage-td2474810.html">other</a> <a href="http://www.nabble.com/Error-Assign-activity:-selectionFailure--Fault-Data-is-null-td17547322.html">postings</a>, and discovered that the attribute could be <a href="http://wiki.open-esb.java.net/Wiki.jsp?page=Process%20Level%20Ignore%20Missing%20From%20Data">placed at the process level</a> or at the individual copy activity level. Jeff Sexton also has a <a href="http://jsexton0.blogspot.com/2009/01/openesb-bpel-assignment-tips.html">nice post</a> on the assign issue. </p>
<p>In <a href="http://blogs.sun.com/javacapsfieldtech/entry/hl7_processor_demonstration_java_caps">Michael’s tutorial</a> he does in fact place the attribute at the process level (see p.95 of the <a href="http://mediacast.sun.com/users/Michael.Czapski-Sun/media/00_HL7_Example_Development_Instructions_Final.pdf">PDF document</a> which accompanies his tutorial). Placing it at the process level is not very attractive because it will mask the absence of mandatory fields. </p>
<p>When placed at the copy element level, it seems to fail. Here’s the error I see, as output in the <a href="https://glassfish.dev.java.net/">GlassFish</a> console window:</p>
<p>BPCOR-6151:The process instance has been terminated because a fault was not handled; Fault Name is {<a href="http://docs.oasis-open.org/wsbpel/2.0/process/executable}selectionFailure;">http://docs.oasis-open.org/wsbpel/2.0/process/executable}selectionFailure;</a> Fault Data is null     <br />com.sun.jbi.engine.bpel.core.bpel.exception.StandardException: I18N: BPCOR-3023: Selection Failure occurred in BPEL({<a href="http://enterprise.netbeans.org/bpel/HL7Processor/bpHL7Processor}bpHL7Processor)">http://enterprise.netbeans.org/bpel/HL7Processor/bpHL7Processor}bpHL7Processor)</a> at line 28!     <br />BPCOR-6129:Line Number is 26     <br />BPCOR-6130:Activity Name is Assign1</p>
<p>Note the line numbers in the above report: the first of these (line 28) is where the selection failure actually occurred, line 26 is the opening tag of the enclosing assign activity element.&#160; Here’s a shot of the source so you can see the corresponding line numbers. I placed all the optional elements together at the start of the assign:</p>
<p><a href="http://lh4.ggpht.com/_1Zdup2KWrzE/ScwEgMzTQqI/AAAAAAAAALA/EiLCmIT4qbM/s1600-h/image%5B2%5D.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="123" alt="image" src="http://lh5.ggpht.com/_1Zdup2KWrzE/ScwEhDigThI/AAAAAAAAALE/2fJKFwEJGbM/image_thumb.png?imgmax=800" width="244" border="0" /></a> </p>
<p>So why doesn’t this work? Is this a bug? Perhaps I’ve run into something which only works in the JavaCAPS product and not in OpenESB?&#160; Shame.</p>
<p>Another unfortunate discovery is that the OpenESB UI in NetBeans 6.5 doesn’t seem to support adding the ignoreMissingFromData at the process level.&#160; In Michael’s PDF he selects the top-level BPEL process scope and uses the property panel to set this attribute.&#160; It doesn’t appear to exist in NB 6.5. In the shot below I’ve tried to capture the same UI as in Michael’s tutorial:</p>
<p><a href="http://lh6.ggpht.com/_1Zdup2KWrzE/ScwEhtw3txI/AAAAAAAAALI/HLA9hLbfJPY/s1600-h/image%5B5%5D.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="84" alt="image" src="http://lh4.ggpht.com/_1Zdup2KWrzE/ScwEiT4y8YI/AAAAAAAAALM/IikjJ7r0LGk/image_thumb%5B1%5D.png?imgmax=800" width="244" border="0" /></a> </p>
<p>Note there’s nothing below the ‘Documentation’ entry: presumably this is additional UI support which you get in the commercial JCAPS product. I’m not that concerned with the missing UI, as long as I can add the attribute in the XML source.&#160; So I edited the BPEL XML, using Michael’s tutorial source as a guide. It’s easy to add the process-level attribute; only the namespace prefix had to be changed:</p>
<p>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;    <br />&lt;process     <br />&#160;&#160;&#160; name=&quot;bpHL7Processor&quot;     <br />&#160;&#160;&#160; xmlns:ns3=&quot;<a href="http://www.sun.com/wsbpel/2.0/process/executable/SUNExtension&quot;">http://www.sun.com/wsbpel/2.0/process/executable/SUNExtension&quot;</a>     <br />&#160;&#160;&#160; ns3:ignoreMissingFromData=&quot;yes&quot;     <br />&#160;&#160;&#160; targetNamespace=&quot;<a href="http://enterprise.netbeans.org/bpel/HL7Processor/bpHL7Processor">http://enterprise.netbeans.org/bpel/HL7Processor/bpHL7Processor&quot;</a>     <br />&#160;&#160;&#160; xmlns=&quot;http://docs.oasis-open.org/wsbpel/2.0/process/executable&quot;</p>
<p>So another clean/build/deploy and … it still didn’t work. So now I’m stuck, and I hate being stuck. It’s almost enough to put me off the product.</p>
<p>The impression I get is that BPEL is great for very simple maps and transforms, but anything complex quickly becomes awkward. I haven’t gone beyond ‘simple’ so far, so I’m getting a little concerned. The pretty visual tools and <a href="http://www.netbeans.org/">NetBeans</a> integration are cool, but the complexity overhead seems high. It reminds me of Microsoft’s BizTalk product from a few years back – a lot of fiddly config, and not being able to ‘see the wood for the trees’.&#160; </p>
<p>But I want to persevere with <a href="https://open-esb.dev.java.net/">OpenESB</a>: something about this product suggests that you need to reach a certain level of enlightenment, after which everything becomes clear and the benefits outweigh the overheads. I’m just not there yet.</p>
<div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:f1b0e9a2-4480-4413-aa49-c228d0ff58e5" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati Tags: <a href="http://technorati.com/tags/OpenESB" rel="tag">OpenESB</a>,<a href="http://technorati.com/tags/NetBeans" rel="tag">NetBeans</a>,<a href="http://technorati.com/tags/BPEL" rel="tag">BPEL</a></div>
]]></content:encoded>
			<wfw:commentRss>http://roger.searjeant.net/wp/2009/03/problem-with-openesb-bpel-assign/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>OpenESB and HL7</title>
		<link>http://roger.searjeant.net/wp/2009/03/openesb-and-hl7/</link>
		<comments>http://roger.searjeant.net/wp/2009/03/openesb-and-hl7/#comments</comments>
		<pubDate>Wed, 11 Mar 2009 23:24:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[HL7]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[NetBeans]]></category>
		<category><![CDATA[OpenESB]]></category>

		<guid isPermaLink="false">http://roger.searjeant.net/wp/2009/03/openesb-and-hl7/</guid>
		<description><![CDATA[Technorati Tags: Java,OpenESB,HL7,NetBeans
As well as looking at Apache Camel for healthcare integration, I have also been spending time with Sun’s OpenESB product.&#160; OpenESB is the open-source counterpart of the Java CAPS product, a mature and well-supported Enterprise Service Bus (ESB) built on the Java Business Integration (JBI) standard.
OpenESB is delivered along with the GlassFish application [...]]]></description>
			<content:encoded><![CDATA[<div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:e8b41146-040e-48a7-be6c-b963358b086b" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati Tags: <a href="http://technorati.com/tags/Java" rel="tag">Java</a>,<a href="http://technorati.com/tags/OpenESB" rel="tag">OpenESB</a>,<a href="http://technorati.com/tags/HL7" rel="tag">HL7</a>,<a href="http://technorati.com/tags/NetBeans" rel="tag">NetBeans</a></div>
<p>As well as looking at <a href="http://camel.apache.org">Apache Camel</a> for healthcare integration, I have also been spending time with Sun’s <a href="https://open-esb.dev.java.net/">OpenESB</a> product.&#160; OpenESB is the open-source counterpart of the <a href="http://www.sun.com/software/javaenterprisesystem/javacaps/index.jsp">Java CAPS</a> product, a mature and well-supported Enterprise Service Bus (ESB) built on the <a href="http://jcp.org/en/jsr/detail?id=208">Java Business Integration</a> (JBI) standard.</p>
<p>OpenESB is delivered along with the <a href="https://glassfish.dev.java.net/">GlassFish</a> application server (v2) when you install the <a href="http://www.netbeans.org/features/soa/index.html">SOA extensions</a> to the <a href="http://www.netbeans.org/">NetBeans</a> IDE.</p>
<p><a href="http://blogs.sun.com/javacapsfieldtech/">Michael Czapski</a> of Sun is an excellent source of information on healthcare-related application of the CAPS / OpenESB product line. He has created a really substantial demonstration project based on a healthcare integration scenario. His <a href="http://blogs.sun.com/javacapsfieldtech/entry/hl7_processor_demonstration_java_caps">blog entry</a> and the associated downloads (and screencast) are well worth getting hold of.&#160; The screencast and writeup are based on Java CAPS, the commercial product which provides a few nice UI improvements and I believe some additional tools which the OpenESB product does not have.</p>
<p>I decided to go through Michael’s complete tutorial, using NetBeans 6.5 and the bundled OpenESB / GlassFish combination, building the solution and making notes as I went along. I’ll put the source code for the NetBeans (6.5) and OpenESB project group up on a publically available Assembla Subversion space (URL to follow), in the hope they may be useful to others who want to use OpenESB to do a similar thing.</p>
<p>As already mentioned, the differences between Java CAPS and OpenESB are superficially small, so if you are already familiar with one or other product you probably only need Michael’s notes and material. However, if you’re relatively new to OpenESB (as I am), there are a few places where the absence of JavaCAPS tooling means you need to know what you’re doing to patch-up the OpenESB solution. </p>
<p><strong>Getting Started</strong></p>
<p>My first big lesson was getting a correct / compatible set of NB plugins and libraries installed. The zip archive provided by Michael appears to contain everything you need, including the XSDs, NB plugins and encoder libraries. As the article was published very recently, I assumed these were the latest versions so tried to configure my NB 6.5 instance using these.</p>
<p>I followed the instructions for installing the encoder library (first uninstalling the existing one), then installing the NB plugins. However, the plugin installation just wouldn’t go ahead:</p>
<p><a href="http://lh5.ggpht.com/_1Zdup2KWrzE/SbhIGsg69II/AAAAAAAAAKg/-fJ59MiofMo/s1600-h/image%5B5%5D.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="237" alt="image" src="http://lh4.ggpht.com/_1Zdup2KWrzE/SbhIHmzdsbI/AAAAAAAAAKk/NEFznESjyeU/image_thumb%5B1%5D.png?imgmax=800" width="244" border="0" /></a> </p>
<p>I tried various combinations but in the end had to uninstall GlassFish v2 and run the NB installer again to reinstall GF plus the OpenESB bits. Fortunately, this is actually quite a quick process, and puts everything back as it was.</p>
<p>I won’t go through all my subsequent false-starts, but simply tell you to download a matched set of the latest versions from this location:</p>
<p><a href="http://download.java.net/jbi/binaries/open-esb-full-install/nbm/latest/">http://download.java.net/jbi/binaries/open-esb-full-install/nbm/latest/</a></p>
<p>The components here should all be compatible. It really is best that you download and install these yourself, so I won’t put them in the Assembla SVN space.</p>
<p><strong>Doing without the Java CAPS Wizards</strong></p>
<p>The most obvious differences when watching the screencast are the degree to which the commercial product contains wizard steps and conveniences for generating all the configuration items. Reasonable enough I think, and so far I have been able to complete every step using OpenESB and NetBeans 6.5.</p>
<p>When creating the concrete WSDL definitions with the HL7 bindings, the wizards in the Java CAPS product (seen in Michael’s screencast) do make the whole process slightly simpler. But if you take a little time to understand what these wizards are actually doing in the generated WSDL, it’s not too hard to complete the steps manually.&#160; That’s easy to say now, but I should ‘fess-up and admit that it took me a little while to spot what I hadn’t done, a couple of times. </p>
<p>For example, once I’d completed the HL7Consumer_CA_A01_A03Delim_HL7In WSDL (sorry Michael, I’m not a big fan of your naming convention!), I simply couldn’t add it to the Composite Application design surface: the tutorial document instructions didn’t appear to work. I could see the WSDL in the list of available WSDLs and select it – but could not add it to the canvas, and couldn’t see any error message to tell me why.</p>
<p>After a cup of tea and a biscuit and a bit of careful thought, I realised why. The HL7 protocol properties were completely missing from the port declaration in the Services section.&#160; It’s easy to fix this, using the context menu commands:</p>
<p><a href="http://lh5.ggpht.com/_1Zdup2KWrzE/SbhIIGWcuDI/AAAAAAAAAKo/y81KK4cQfMQ/s1600-h/image%5B8%5D.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="161" alt="image" src="http://lh4.ggpht.com/_1Zdup2KWrzE/SbhIInihaQI/AAAAAAAAAKs/OOuvr3ypWgE/image_thumb%5B2%5D.png?imgmax=800" width="244" border="0" /></a> </p>
<p>Then edit the properties in the property grids. Of course, in the JavaCAPS product the wizards prompt you for these properties and create the related WSDL bits behind the scenes.&#160; I don’t like depending on wizards. Fortunately the NetBeans tooling gives you just enough convenient UI to hide the underlying cruft, but also lets you work at the XML / source level and see what’s going on down there.</p>
<p>That’s probably enough for this post.&#160; There’s so much more to write but I need to knock it into shape before I publish.</p>
]]></content:encoded>
			<wfw:commentRss>http://roger.searjeant.net/wp/2009/03/openesb-and-hl7/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Camel, HL7, HAPI and NAK Messages</title>
		<link>http://roger.searjeant.net/wp/2009/02/camel-hl7-hapi-and-nak-messages/</link>
		<comments>http://roger.searjeant.net/wp/2009/02/camel-hl7-hapi-and-nak-messages/#comments</comments>
		<pubDate>Tue, 17 Feb 2009 17:02:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Camel]]></category>
		<category><![CDATA[HAPI]]></category>
		<category><![CDATA[HL7]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[healthcare]]></category>

		<guid isPermaLink="false">http://roger.searjeant.net/wp/2009/02/camel-hl7-hapi-and-nak-messages/</guid>
		<description><![CDATA[The previous couple of posts were related to using Apache Camel in a healthcare integration setting.  The HL7 support in Camel is built on the HAPI library which provides Java classes for most of the HL7 v2 variants, plus MLLP support.  So in integration terms, HL7 can be considered a combination of an endpoint type [...]]]></description>
			<content:encoded><![CDATA[<div xmlns='http://www.w3.org/1999/xhtml'>The previous couple of posts were related to using Apache Camel in a healthcare integration setting.  The HL7 support in Camel is built on the <a href='http://hl7api.sourceforge.net/'>HAPI library</a> which provides Java classes for most of the HL7 v2 variants, plus <a href='http://www.hl7.org/v3ballot/html/infrastructure/transport/transport-mllp.htm'>MLLP</a> support.  So in integration terms, HL7 can be considered a combination of an endpoint type (the MLLP/TCP protocol) and a message format (the HL7 ER7 or XML representation).<br/><br/>The Camel architecture nicely isolates endpoint-types and message-structure types in <a href='http://camel.apache.org/components.html'>Components</a> and <a href='http://camel.apache.org/data-format.html'>DataFormats</a>, respectively.  A Component is something which knows about a specific communication mechanism or protocol: in the case of HL7, the <a href='http://camel.apache.org/hl7.html'>Camel HL7 Component</a> knows how to exploit the underlying Apache Mina library to exchange delimited text messages using the HL7 protocol.  The Component also acts as a factory for Camel Endpoint objects: it hands out individual Endpoint objects, each of which represents an instance of the endpoint-type implemented by the Component. <a href='http://camel.apache.org/maven/camel-core/apidocs/index.html?org/apache/camel/spi/DataFormat.html'>Camel DataFormat</a> objects marshal / unmarshal byte-streams or strings to / from Java objects of some type.  This makes it much easier to build content-based routes in Camel.<br/><br/><span style='font-weight: bold;'>HL7 ACK / NAK Messages</span><br/><br/>In the previous post, one of the issues I had to deal with in the example route was returning an ACK or a NAK to the message originator. The HL7 protocol uses a positive-acknowledgement scheme: receivers will ACKnowledge (ACK) messages they understand and can process, and will Negatively AcKnowledge (NAK) anything else.  The HAPI library provides support for this in the makeACK method of the <a href='http://hl7api.sourceforge.net/xref/ca/uhn/hl7v2/app/DefaultApplication.html'>DefaultApplication</a> class.  Unfortunately, this is less helpful when we need to return a NAK.<br/><br/>Recall that the first part of my route was checking to see whether the right kind of message has been received. In the sample, I was testing just the message type (MSH-9.1) and the trigger event (MSH-9.2) fields.  In reality, you would probably also want to check that the sender was using the same version of HL7 as you are expecting: you can do this by examining the value of field MSH-12. It will become clear why this is important, below.<br/><br/>Suppose the inbound message fails the MSH-9 test. The otherwise() clause in my little route will send the HL7 data (unmarshalled from the stream) to the badMessage() method on my handler bean.  This method expects a single argument of type ca.uhn.hl7v2.model.Message, i.e. a generic HAPI HL7 message object.  The argument can&#8217;t be of a more specific type than this because the Camel route builder cannot know in advance what will be received and unmarshalled from the endpoint; it can only assume it will be a HAPI Message. <br/><br/><span style='font-weight: bold;'>Constructing an ACK</span><br/><br/>In the badMessage method, I need to construct a HL7 NAK message to be returned to the caller. HL7 ACKs and NAKs share the same structure: we just need to change the value of one field (and optionally add a diagnostic message) to indicate NAK. The obvious solution is to call DefaultApplication.makeACK, mentioned earlier, and modify the returned structure as necessary.  MakeACK&#8217;s single argument is a single Segment, the intention being that the caller passes-in the MSH segment of the original inbound message:<br/>
<pre>Message makeACK(Segment inboundHeader)</pre>
<p>The reason for this is that the makeACK method needs some values from the inbound MSH segment to populate fields in the Message Acknowledgement segment (MSA) of the ACK correctly. An HL7 ACK (or NAK) must be associated with the original message (i.e. the inbound message being ACK&#8217;d or NAK&#8217;d) so that the originator can distinguish which of its outbound messages is being acknowledged or rejected. This is done using the Message Control ID, which is field 10 of the MSH segment.<br/><br/>But remember where we are in the Camel route: we have an invalid message in our hands. We don&#8217;t know the exact class-type of the inbound message object so we can&#8217;t cast the Message to a specific type. And the Message interface itself doesn&#8217;t provide a way to extract the MSH segment. So how are we going to call makeACK(Segment)?<br/><br/>We cannot simply new-up an instance of some specific message type (e.g. a version 2.3 ORM^O01) and use its MSH segment as the makeACK argument:<br/><br/>    // Assume ca.uhn.hl7v2.model.v23.*<br/>    <br/>    ORM_O01 orm = new ORM_O01();<br/><br/>    ACK ackMsg = (ACK)DefaultApplication.makeACK(orm.getMSH());        // &lt;&#8211; Bang! <br/><br/>    // Set MSA.1 to Application Reject (AR)<br/>    ackMsg.getMSA().getAcknowledgementCode().setValue(&#8220;AR&#8221;);<br/><br/>    // etc.<br/><br/>This will compile, but won&#8217;t work. The manufactured ORM_O01, despite being an instance of a specific version of HL7, is not properly constructed, in several ways. First, MSH-12.1 will not contain &#8220;2.3&#8243;, which is surprising, given that HAPI should be able to populate MSH-12.1 for a new message instance. If we pass the ORM_O01 MSH to makeACK, it tries to get the value of MSH-12.1 but finds a null. This causes makeACK to fall-back to creating and returning an ACK for version 2.4 of HL7 (this is baked-in to the HAPI code &#8211; I&#8217;m not sure if this is an arbitrary HAPI design decision, or to do with the HL7 spec). And of course we get a ClassCastException at run-time as a result, because we are expecting a v2.3 object.<br/><br/>But even if this did work, isn&#8217;t it ugly? We&#8217;d be baking-in a version of HL7 because we must choose a specific ORM_O01. So how do we create the ACK structure, and how can we make our code work for any version of HL7 supported by HAPI?<br/><br style='font-weight: bold;'/><span style='font-weight: bold;'>Terser to the rescue</span><br/><br/>Fortunately, HAPI provides a handy utility class for parsing and unparsing HL7 messages of arbitrary versions &#8211; the <a href='http://hl7api.sourceforge.net/apidocs/index.html?ca/uhn/hl7v2/util/Terser.html'>Terser</a>. This will let us get hold of the MSH segment from the original message, so we could at least call makeACK with the original MSH:<br/><br/>    // This still depends on the ackMsg decl. being for the same specific version<br/>    // as the original message.<br/>    Terser t = new Terser(originalMsg);<br/>    Segment msh = t.getSegment(&#8220;MSH&#8221;);<br/>    ackMsg = (ACK)DefaultApplication.makeACK(msh);<br/>    ackMsg.getMSA().getAcknowledgementCode().setValue(&#8220;AR&#8221;);<br/><br/>Now when we call makeACK we are passing-in a valid MSH so it will extract the HL7 version number and dynamically create the correct ACK class, using <a href='http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Class.html#forName%28java.lang.String%29'>Class.forName</a>.  But as the comment says, this stilll only works if the compiled-in ACK declaration matches the returned ACK message version. We need to lose the compiled-in ACK declaration, but still find a way to populate the ACK message&#8217;s MSA segment with the right values.<br/><br/>Fortunately, we can use the Terser to set the field values in a version-independent way. This is exactly what DefaultApplication&#8217;s static methods makeACK and fillResponseHeader do.  So I used a combination of the Terser and the guts of DefaultApplication.makeACK to create a couple of helper methods which do the right thing.  I&#8217;ve put the source code on <a href='http://sites.google.com/site/rogersearjeant/healthcare-and-hl7/hapi-ack-nak-message-helper'>this page</a> in my Google site, for anyone who wants to use it.<br/><br/></div>
]]></content:encoded>
			<wfw:commentRss>http://roger.searjeant.net/wp/2009/02/camel-hl7-hapi-and-nak-messages/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Generating PDF from XML with XSL-FO</title>
		<link>http://roger.searjeant.net/wp/2008/09/generating-pdf-from-xml-with-xsl-fo/</link>
		<comments>http://roger.searjeant.net/wp/2008/09/generating-pdf-from-xml-with-xsl-fo/#comments</comments>
		<pubDate>Fri, 12 Sep 2008 15:10:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[HL7]]></category>
		<category><![CDATA[PDF]]></category>
		<category><![CDATA[XSL-FO]]></category>
		<category><![CDATA[healthcare]]></category>

		<guid isPermaLink="false">http://roger.searjeant.net/wp/2008/09/generating-pdf-from-xml-with-xsl-fo/</guid>
		<description><![CDATA[One of the healthcare solutions I&#8217;m working on has to generate diagnostic report documents in a form we can distribute directly (e.g. secure email) to clinical staff.  The diagnostic report text plus the usual patient demographics and such, arrives in a custom XML message from the integration engine.  The solution uses HL7 v2 [...]]]></description>
			<content:encoded><![CDATA[<div xmlns='http://www.w3.org/1999/xhtml'>One of the healthcare solutions I&#8217;m working on has to generate diagnostic report documents in a form we can distribute directly (e.g. secure email) to clinical staff.  The diagnostic report text plus the usual patient demographics and such, arrives in a custom XML message from the integration engine.  The solution uses HL7 v2 elsewhere, but the PAS messaging is exclusively via custom XML (not HL7 v3 XML).<br/><br/>The legacy document-generation subsystem used Word to create the document: a template was created to get the layout and formatting right, and simple placeholders used to mark the locations of the data we would substitute, taken from the XML data.  This approach actually loads Word into memory (on the server!) to do the work &#8211; it&#8217;s slow, memory-hungry and just generally clumsy and ugly. Plus you end up with a Word document, so the clinician needs Word (or the reader) to view it.<br/><br/>PDF is a more acceptable format, in my view.  We can secure and digitally sign the document when we generate it to prevent subsequent changes.  Recipients can view PDF on any platform with a free viewer.  The problem for me was how to generate the PDF programmatically, from the XML data. There are probably several ways to do this, but I chose XSL-FO and the <a href='http://xmlgraphics.apache.org/fop/'>Apache FOP</a> project mainly because I wanted to avoid using a proprietary PDF generator product (there are <a href='http://www.xslfast.com/'>lots</a> <a href='http://www.renderx.com/'>out</a> there), but also since XSL-FO can do more than just generate PDF.<br/><br/>First problem: how do you create the FO which is the &#8217;shape&#8217; of the generated document?  Of course, you could simply read through all the manuals and write one from scratch. Well,  I&#8217;m just plain lazy, you see, and I don&#8217;t want to do all that.  I want to take my nice OpenOffice document, or even Word document, and have a tool create an XSL-FO for that document. And I&#8217;d like the tool to be free (there are commercial tools of course, but I&#8217;m cheap).  Does such a thing exist?<br/><br/>It does!  Amazingly, precisely this facility exists in <a href='http://www.abisource.com/'>Abiword</a>: not my favourite word-processor by a long, long way, but a good solution for this particular problem.  OpenOffice should be really good at doing this, as it stores documents natively as XML and already uses FO internally for some style information.  But, despite some promising hints, there is no mature support for this.  This is a real shame: this is just the sort of thing OOo should be capable of, especially as it&#8217;s apparently half way there already. <br/><br/>Here&#8217;s what I managed to find on the OOo site:<br/>
<ul>
<li>Some OpenOffice <a href='http://wiki.services.openoffice.org/wiki/Xml#Filters_and_Conversions_based_on_OpenDocument.2FOpenOffice.org_XML'>transforms and things</a>.</li>
<li>And <a title='this one' href='http://wiki.services.openoffice.org/wiki/ODF_Toolkit/Efforts/ODTransform' id='bv.5'>this one</a> talks about ooo2xslfo but that project looks as if it&#8217;s just a SVN repository &#8211; not sure I have time to play with that.</li>
<li>The OOo XML site has <a title='a page on XML filters' href='http://xml.openoffice.org/filter/' id='x5-s'>a page on XML filters</a> too.<br/></li>
</ul>
<p>Important to mention also that Microsoft does have an XSLT which you can apply to Word documents to generate XSL-FO. It&#8217;s freely downloadable from <a href='http://www.microsoft.com/downloads/details.aspx?FamilyId=E0FAA0AF-A185-4296-B74D-A9FE870C92CC&amp;displaylang=en'>this download page</a>.  I tried this, and it works, but the resulting FO is much messier than Abiword&#8217;s.<br/><br/>Once you have the FO, the obvious step is to embed it in an XSL, add xsl:value-of elements in the appropriate places and use a transform to populate the template.  This is the approach I took for the proof-of-concept and it worked well. The resulting PDF looks almost right &#8211; with a small amount of FO-tweaking, we should have something very usable.<br/><br/>But using XSL means loading up and running the (trivial) transform which I think may be very inefficient for such a simple case, plus it requires the FO to be edited.  I&#8217;ve decided to use a  simpler approach (using <a href='http://www.stringtemplate.org/'>StringTemplate</a>) which I hope will be more efficient, and requires less FO editing (just the addition of $fieldName$ placeholders).  All we need is a list of (fieldname, XPath) pairs for our XML message, in order to drive this template.  Of course, most other applications will need the power of XSL (e.g. to deal with tables of entries): I&#8217;m only avoiding it here because the data is so simple.<br/><br/>This is something we&#8217;re bound to want to do again, in different contexts, so I&#8217;m using this project and the prototype to build a tool-chain and utilities for this, so we can use the same approach more easily next time.<br/><br/></div>
]]></content:encoded>
			<wfw:commentRss>http://roger.searjeant.net/wp/2008/09/generating-pdf-from-xml-with-xsl-fo/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
