I've been following the discussions on the SOAP vs. REST and HITSP selected transports. Some of the details are well documented on John Halamka's blog, and in other articles I've written here in response. In a way, it seems to me to be more of a public dialog about the percieved simplicity of REST opposed to the percieved difficulty in implementing the HITSP selected transport (XDR).
I'm going to relate some numbers about XDS. If you understand XDS and XDR, you understand that the XDS outbound provide and register transaction is EXACTLY the same to a XDS repository, or to an XDR Document Consumer. You did say reuse and simplicity were important, right? What could be easier than that. Processing the XDR inbound transaction is actually easier than the outbound transaction.
But if you are trying to implement the transport protocol yourself, you've already attacked the wrong problem and it's a waste of your time. But even though it's a hard problem, it's NOT that hard -- I should know having done it thrice. Let me tell you a little bit about my experiences here:
From Scratch is The Hard Way
Raw XDS (without audits, TLS or CT) cost me about six weeks of effort six years ago (the first year) to "build from scratch" in Java (in about 4000 lines of code). That INCLUDES connectathon testing. There's another 3000 lines of code that dealt with CDA stuff that was product specific that also went into the effort. The XDS part was the easy bit.
A couple of years ago, I rebuilt XDS transactions using a Java ESB and XSLT transforms over the CDA document. I did that in four weeks of effort, INCLUDING connectathon testing. The magic is all in about 5000 lines of XSLT, about 2000 of which I wrote. About 200 lines of XSLT are a code generator, and 3000 of those are machine XSLTs generated from data contained within the IHE PCC Technical Framework Of the remaining: 800 are hand tuned XSLT for the most common PCC entries, 400 in cda generation utilities, and another 600 in a converter that takes a CDA document and turns it into an XDS.b Provide and register transaction. There's a little bit of custom Java glue in the ESB. This is my main toolkit to test IHE profiles, and I've used it with four different profiles, and three different sources for the data that went out in two different connectathons. I routinely test the IHE profiles I help author at connectathon because it's one way for me to prove that they work and that IHE is not headed into the stratosphere.
TLS
If your issue is with TLS, I also feel your pain, but rather than make you go through it, I want you to learn from mine. The first time I dealt with TLS (five years ago), I spent much time (four weeks) on it to get it perfect, I wrote a FAQ on it that is fairly well known in IHE circles. It includes source code to make TLS work with the IHE ATNA profile (again in Java). The code base for this is VERY small (500 lines), the documentation in the FAQ is MUCH more important and hard won knowledge. The audit trail code was more slogging than craft, and was about 1500 lines (that's not in the FAQ). Last year, another engineer with a similar build as I and long hair wondered why everyone was asking him ATNA questions (they were looking for me) -- but he'd read the FAQ and had all the answers. Maybe this year it'll be you.
In the overall scheme of things, 8-10 weeks to build and test a secure transport protocol from scratch is really a drop in the bucket, but I love my ONE day experience. I implemented XDS edge system transactions again, and got it working in ONE day using open source tools (including TLS and Auditing). While that time obviously doesn't include connectathon testing -- those same tools have been through three years of connectathon tests by numerous vendors. I challenge you to do that in a day the REST way.
Open Source is The Easy Way
Other people and organizations have addressed the Document Source side of the "provide and register" transaction repeatedly, and have provided freely available open source Java solutions. I can count six in my head, but Open Health Tools is probably the most well known in the US, and there's also the Federally sponsored CONNECT project. If you are a C#/.Net geek, dig a little into the Microsoft open source registry project. You'll find some good documentation and sample code C#/.Net code to support the provide and register transaction there as well. It's a little less refined, but you should be able to make it workable.
As for the inbound side, if all you want is the document attachments, nothing could be easier than the following few lines of Java (ripped off from a connectathon tested implementation):
public void visitAttachments(SOAPMessage m, Visitor v)
{
Iterator i = m.getAttachments();
if (i == null) return;
AttachmentPart part = (AttachmentPart)i.next();
while (part != null)
{ v.visit(part);
part = (AttachmentPart)i.next();
}
}
I'm sure a similar C# implementation exists, I'm just not a C# coder, and don't know much about WCF. Look to the documentation on the Microsoft open source site for implementing the Document Consumer. Some of those same patterns will work as the reciever of the SOAP message to unpack the attachments.
If you want to do more with the inbound metadata associated with those parts you can readily do that. The metadata elements are only a single XPath query away from the XML body of the SOAP message. These queries are about two lines of code in Java or C#, and any relatively experienced XML geek will know how to find it. If you aren't that experienced, there's a dozen or so books at your local bookstore targeting your favorite programming language.
Using open source does not involve overly complex code. The key is being willing to read through an understand a little bit about what someone else did, and learn from it. If you have to write more than 200 lines of code to make an open source based XDR implementation work (not finished, just working), I'd be very surprised. If it takes you more than two days to get both halves working, I'd also be surprised. If you want some pointers, drop me a line.
It was fun once, but now I've been there and done that. Writing transports myself is something that I've learned I'd rather let someone else do. That way, I can focus on the real issues. So let's give this debate a rest.
Keith
NOTE 1: I'm a big fan of open source. However, please don't take my mention of these tools as any endorsement by me or my employer for these specific tools. You must evaluate the suitability and fitness of any software you use for your own purposes.
NOTE 2: I count my lines of code raw, and have about a 33% comment to code ratio (in java), mostly in javadoc. And yes, I remember these numbers... I've been gathering personal metrics for years.
Hi Keith,
ReplyDeleteI regularly follow your great blog - and this time I have a little comment on the SOAP vs REST debate.
One thing is to clearly distinguish application code from interfacing. Clearly developing a full-fledged production-ready XDS registry and/or repository is much more than just the bare minimum of domain logic the XDS profile imposes on you. Most of the time, your application not just acts as a pure backend thing (as you mentioned, there's OSS stuff available), but also to provide added value (e.g. some graphical user interface). At the end, from a vendor's perspective, you have to make the difference in competition.
The second thing is to discriminate the protocol level and the business level of an interface. SOAP vs REST is only about the protocol level. (I consciously ignore discussing the choice of ebXML here). While the business level (i.e. data model) probably wouldn't change at all, XDS seems to be a perfect fit for a resource-oriented interface to me - it would be a nice exercise to reexpress the transactions that way. I'm not saying the decision for SOAP was wrong (after all, before XDS.a, SOAP was cutting-edge, and REST not). But I'm very convinced that dealing with SOAP (and one of the numerous WS frameworks) distracts your attention much more than necessary from the real business value that your XDS-compliant application is supposed to deliver. (And I'm haven't even mentioned platform interoperability, which - even in times of WS-I - is just annoying).
To support your Open Source affinity, I'd like to add the Open eHealth Integration Platform (IPF, http://gforge.openehealth.org/gf/project/ipf/) to the list. Its dedicated IHE support encapsulates both client- and server-side interfaces into very few Java/Groovy statements, e.g.
// Entry point for Retrieve Document Set
from('xds-iti43:myService')
// Validate and convert the request
.validate().iti43Request()
.convertBodyTo(RetrieveDocumentSet.class)
// everything below is your business logic
for receive a RetrieveDocument request including ATNA auditing, proper handling of large documents, request validation and transformation from the raw ebXML into an object model very close to what is specified by XDS. No need to directly deal with SOAP WebServices anymore. The XDS tutorial (http://repo.openehealth.org/sites/ipf/manuals/ipf-2.0-rc1/XDS%20repository.html) demonstrates how a (admittedly very simple) registry and repository can be done in far less than 1000 LOCs...
best regards
Christian Ohr