Tuesday, 27 August 2013

Bridging Mule and MSMQ with ZeroMQ

Hearing the words Mule and Microsoft's MSMQ in the same sentence sends a shiver down my spine. I remember once, Mule guru John D'Emic and me had spent a considerable amount of time and patience getting Mule and MSMQ to talk to each other through DCOM. The major factor that contributed to this unpleasant experience was our ignorance of the numerous security measures imposed by Windows to restrict DCOM access. The morale of this story is unless you have a veteran Windows administrator at your disposal, avoid the DCOM route.

So which choices do we have other than DCOM? JNI sounds promising but you are then sacrificing Mule's platform independence. Here's an idea: introduce a messaging bridge between Mule and MSMQ. The bridge can be implemented in any language that facilitates interaction with MSMQ. C# is an attractive option.

We still have to consider which middleware to use for exchanging messages between the bridge and Mule. There are many alternatives and among them is ZeroMQ. I think ZeroMQ is a good candidate for several reasons:
  • It supports asynchronous communication
  • You're not adding another component to your architecture
  • It's well documented in addition to having a low learning curve
  • A ZeroMQ transport [1] and binding are available for Mule and C# respectively
  • It will more than likely satisfy your message throughput requirements
In as little as 15 minutes I developed a simple bridge in C#:

The above code should be self-explanatory but I've put comments for your convenience.

Here's the Mule 3 app dispatching messages to the bridge:

On receiving an HTTP request, Mule leverages the ZeroMQ transport to send asynchronously the request's payload to the bridge.

In all likelihood, the illustrated bridge code for Mule-MSMQ interoperability won't serve all your needs. I can think about a dozen features that a developer would want such as destination queues resolved at run-time, an agreed format for message content, and etc. But hey, at least it's a start :-)

1: I've recently replaced the transport's ZeroMQ C++ library with a pure Java implementation of ZeroMQ.

Monday, 19 August 2013

JRuby Complex Classes in Java Method Signatures

As documented in the JRuby wiki, java_signature changes a method's signature to match the signature string passed to it:

Observe that the classes in the method signature are primitive. What if we use a complex class as a parameter type?

Running the above code will give you the following NoMethodError message:

The way I went about using complex classes in signatures is to utilise add_method_signature instead of java_signature:

add_method_signature expects the first argument to be the name of the method that will have its signature changed. For the second argument, it expects it to be a list of classes. The list's first item is the return class (e.g., void) while the subsequent items are the signature's parameter classes (e.g., int and MyClass). Note that I invoke become_java! on the complex class. This tells MyClass to materialize itself into a Java class. The false flag is needed so that JRuby's main class loader is used to load the class. Without it, you'll be greeted by a java.lang.ClassNotFoundException.

Saturday, 10 August 2013

JRuby CXF: A Gem for Creating SOAP Web Services

It seems to me that Web Services don't receive much love from Rubyists. In fact, of the two Ruby projects I know that add Web Service support (SOAP4R and ActionWebService), both appear to be inactive. Someone might say that if Web Services are a must, then avoid Ruby or put an integration layer between your Ruby application and the client/service. From my experience, life is not always that simple and these solutions might not be applicable. 

The Java ecosystem has a popular and well-supported open source project that is used to build SOAP Web Services and clients. This project is called Apache CXF. On one fine sunny day I asked myself: "Wouldn't it be great if I could publish a Web Service from Ruby using Apache CXF?". Almost immediately I put that thought away. Trying to integrate a Java library into Ruby is, well, hard in my books. But then JRuby popped into my mind. JRuby is the Ruby language implemented in Java. This means that Ruby and Java objects talk to each other with relative ease.

Seeing the potential in the idea, last week I set about developing a JRuby wrapper gem for CXF. I must admit it was more challenging than I thought but at the end I was happy with the results. The bulk of the work was customising the Aegis data binder so that it could map RubyObject instances.

The first step to using the gem is installing it:

A code example is in order here:

Publishing the above class as a Web Service means requiring the gem and including the module CXF::WebServiceServlet:

Including WebServiceServlet causes the class to become a regular Java servlet. This implies that any servlet container can load the Web Service. For this example, I'll load the Web Service using an embedded Jetty:

Running the example requires two libraries to be available in the Java classpath: CXF 2.7.6 and Jetty 8.

Accessing the URL http://localhost:8080/hello-world?wsdl with a browser will display the following WSDL:

You'll note that the operations are missing from the WSDL. This is because I didn't tell CXF to expose any of the methods in the class HelloWorld as Web Service operations. Let me do that now:

expose tells CXF to publish the method denoted by the first argument (i.e., :say_hello). The second argument in expose is a map. It should have at a minimum the following entries:
  1.  expects - maps to an ordered list of hashes where each hash corresponds to a method parameter and its expected type.

  2.  returns - maps to the expected return type (e.g., :string).
Re-executing the example will give out this WSDL:

The gem supports various options to customise the WSDL. For instance, the service name and namespace can be changed:

The complete list of options is found in the project repository's README file .

Till now I've assumed that a Web Service operation will only accept simple types. In the real world we're more likely to be using complex types:

I've added two classes in the example: Animal and Person. It is necessary to include the CXF::ComplexType module so that CXF can derive an XML schema from these classes and embed the schema in the WSDL. A complex type element is declared using the method member. A member needs at least a name for the element and its type. You could also declare whether a property is required as seen in the member pet. The required option defaults to true if not specified.

Note that now say_hello and give_age are expecting a Person object instead of primitive types and they are accessing the object via accessors. Behind the scenes the gem creates an accessor for each member that is declared.

I hope I've given you enough info to get started out with the gem. My plan is maintain JRuby CXF as I believe it could be useful for those who aren't happy with the current alternatives. Of course, if you find an issue with the gem, I'd be more than happy to accept code contributions ;-).