Friday, August 13, 2010

An easy, useful, NMR: Monsieur Nodet, vous êtes une légende.

I was discussing the ServiceMix NMR component this week with a colleague; and my interest was piqued enough to take a fresh look at this little fella. I grew to dislike the JBI NMR some time ago, and have written about these feelings a number of times on this blog. But its time to draw a line under those dark times, and look to the future. And, in the brave new world of ServiceMix 4, the new NMR becomes lightweight, liberating, and startlingly useful.

Rather than explain the technology first, let's talk about the problem that it might solve. In ServiceMix, you can deploy integration or business logic as OSGi bundles - this much we know. Now, say you want to send some information between two bundles: how can you do it? There are a number of options open to you - here's some of the most popular options.

  • Use OSGi services. I'm a huge fan of the POJO-based approach that comes with OSGi services. It's easy to use. Drawbacks? There are two I can think about - whether they're relevant to your use case will depend on, well, your use-case. First, the call is always going to be executed synchronously on the callers thread. If you've got lots of throughput going through the system, this may not be desirable. Second, in order to invoke on the OSGi service, you will need to marshal your incoming payload into POJO objects: maybe this marshaling is something you simply don't want to do. Maybe you just want to pass data through the system as fast as you can.

  • Use JMS queues. We love ActiveMQ, and ServiceMix is tightly integrated with ActiveMQ. But it seems that forcing the use of a JMS queue just to send some information from A to B, in the same JVM, feels like overkill - despite all the underlying optimizations available in ActiveMQ for in-memory messaging.

  • Use the NMR. Ching! The penny drops. The ServiceMix NMR allows you to send anything to another bundle, and allows you to do this either synchronously or asynchronously. So: you get choice on whether you want your code to be handled on a separate thread. And (and this is the best bit) the NMR, unlike the old JBI NMR, does not demand that the payload be XML. You could send your granny through. If your Granny was a Java Object. If it wouldn't cause too much confusion, I'd vote for a name change, and call this the Denormalized Message Router (DMR), as it no longer tries to enforce a canonical format.

Playing with this, I put together a little demo in a few minutes where one bundle did a file pickup (of a non-XML file) via Camel, sent the file to an NMR service in another bundle over the NMR, where the file is processed. Worked a treat. No pain. I was shocked at how easy this worked. The other thing that shocked me was how simply the Camel-NMR component is to configure. I was expecting tricks like 'you must provide an XML QName to describe your endpoint', or any number of other intellectual land-mines. But the short page of documentation on the Camel website was all I needed.

So where do I go from here? I feel really, really positive about this NMR now, in a way that I didn't before. It's become a technology I can use without having to worry about the mechanics underneath, like how I can drive my car without having to know how my engine works.

I must compliment Guillaume Nodet's work in this area. Taking the hard stuff out, and leaving a very useful and very usable NMR core, is smart thinking.


Ben ODay said...

Ade, good post. NMR does seem promising...still trying to get my head around the options though. I started a similar comparison and would appreciate your feedback on it...thx

Ade said...

Nice one boday! I see you've added some of the other alternatives, for example, using dOSGi (which is really just normal OSGi services with potential for transparent remoting), and alternatives such as REST. You've broadened the playing field! I think once you consider having bundles talk *outside* of the JVM, then you can of course open up many, many possibilities. Within the JVM though, I'm still thinking that NMR or vanilla-OSGi services is the way to go.


Unknown said...

Ade - Caching!

Remember my comment in that dreadful Slough hotel?

cmoulliard said...


To be complete, the component vm:// of camel allows to interconnect routes between osgi bundles. So I'm not quite sure that NMR is the right choice and absolutely required.



Ade said...

Hi Charles,

I remember talking to Guillaume and James about the vm:// component a while back, and I remember that they strongly recommended NMR over vm://; I think they feared that the vm:// component was perhaps hacky and subject to classpath subterfuge when deployed in OSGi container like Karaf or ServiceMix. Will have to defer to Guillaume though to clarify if vm:// on it's own becomes a valid alternative!