Tuesday 15 January 2013

SOAP over ZeroMQ with Apache CXF

You're probably asking yourself one of these two questions on reading this post's title:
  1. Who in his right mind would use SOAP as a data format for ØMQ?
  2. Why the heck would I want to have SOAP on top of ØMQ as opposed to HTTP?
For the first question, consider a system requiring:
  • A return address pattern such as the one offered by JMS and MSMQ.
  • Guaranteed message delivery. 
  • Encryption and authentication of messages.
ØMQ wasn't designed to cover these requirements so it's up to the developer to come up with a solution. The developer can re-invent the wheel and build the solution from the ground up. But why do that when other folks have already taken the trouble of writing and implementing standards that address these concerns independent of the transport used? I'm speaking of WS-*. Using a SOAP engine, we can leverage WS-* standards like WS-Addressing, WS-Security, and WS-ReliableMessaging to address the above requirements and more. 

Focusing on the second question, several motivations exist for using SOAP on top of ØMQ. The first that may pop into mind is the desire to reduce latency as ØMQ incurs less overhead than HTTP. For me, strong motivations include:
  • Leveraging ØMQ's low-level and high-level patterns such as publish-subscribe and pipeline. 
  • Dispatching messages to services while they're in a disconnected state.

With the "Why?" out of the way, let's figure out the "How?". That is, how to process SOAP messages over ØMQ. Apache CXF is an open-source Java SOAP engine that operates over transports such as JMS, UDP, and of course HTTP. During the holidays, since I had lot of free time on my hands ;-), I extended CXF to support ØMQ as an additional transport

What follows is an example of a Web Service and a client talking with each other over the transport [1]. Consider this WSDL fragment that I wrote, and which the service and client are based on:

The contract describes a service that publishes a single operation called sayHi. sayHi accepts an empty message and returns a string. Line 29 of the WSDL informs us that the service expects sayHi to be invoked using SOAP over ØMQ. Line 43 tells us the service address whereas lines 44-45 give additional necessary details for the client and service to establish communication. Observe that I'm using socket types req and rep for the client and service respectively. This means that the communication between client and service occurs in RPC-style.

I use the the wsdl2java tool that comes with the Apache CXF distribution to generate SEI and proxy classes from the above WSDL. These classes help me develop the WSDL service implementation and the client.

Next, I implement the service:

The service is published using the following code:

From the consumer-side, here's the code:

I write an additional class that triggers the execution of the service and its consumer:

I use Maven from the project's root directory to build the example:

Finally, to run the app:

The output I get is:

You'll find the complete example on GitHub. This example is basic; its purpose is to get you up and running with the transport. In my next post I'll have a more real-world example where I'll show how WS-Addressing's ReplyTo element is be leveraged to implement the return address pattern in ØMQ.

1: You need the Java binding for ØMQ installed on your machine to run the example.

No comments:

Post a Comment