I am busy setting up an integration platform for a customer and I want to see what role Mule can play here. Based on the documentation it could be an important role but that is just the documentation. Of course I want to see it for myself to make sure. The reason why Mule was selected (there are a lot of similar products like OpenESB and ServiceMix) as favorite was because the nice integration with Maven and the ease with which you can setup unit tests. For me the best way to evaluate a product is by using it and getting familiar with it. So I downloaded the newest version (2.2.0), installed it and got myself a book about Mule2 (in this case “Mule 2 A Developer’s guide” from ‘firstpress’). I prefer to use a book to force myself to evaluate the product by a kind of structured way, instead of just jumping from one example to another.
So by going through the book I got to the first example and I also ran into the first challenge. The example given looked like the following situation (I assume Mule is installed correctly):
- Create a Maven project for a Mule project
- Modify the default config file
- Create the necessary Java classes
- Create the test class
- Run the project
I used the Mule Project Archetype:
mvn mul-project-archetype:create -DartifactId=net.pascalalma.mule -DmuleVersion=2.2.0
See the docs for more detail info about the use of this archetype.
To tell Mule what to do you have to supply a config file on the classpath. Default you will get an empty one created by the archetype. I put in the following (according to the example of the book):
<mule> <model name="main"> <service name="Square" > <inbound> <vm:inbound-endpoint path="math" synchronous="true" /> </inbound> <component class="net.pascalalma.mule.Square"/> <outbound> <pass-through-router> <vm:outbound-endpoint path="inverse"/> </pass-through-router> </outbound> </service> <service name="Inverse"> <inbound> <vm:inbound-endpoint path="inverse" /> </inbound> <component class="net.pascalalma.mule.Inverse" /> <outbound> <pass-through-router> <stdio:outbound-endpoint system="OUT"/> </pass-through-router> </outbound> </service> </model> </mule>
As you can see in the config file there are two components defined which are actually just pojo’s like this:
package net.pascalalma.mule; /** * * @author pascal */ public class Square { public Integer square(Integer i) { return new Integer(i.intValue() * i.intValue()); } }
and
package net.pascalalma.mule; /** * * @author pascal */ public class Inverse { public Integer inverse(Integer i) { System.out.println("Doing inverse..."); Integer result = new Integer(-1 * i.intValue()); System.out.println("Expected result = " + result); return result ; } }
Next is to create the class with which we can test the configuration of Mule. I created this class (taken as exampe from the book):
package net.pascalalma.mule.mathservice; import java.util.Map; import org.mule.DefaultMuleMessage; import org.mule.api.MuleMessage; import org.mule.module.client.MuleClient; import org.mule.tck.FunctionalTestCase; public class MathServiceTestCase extends FunctionalTestCase { protected String getConfigResources() { return "mule-config.xml"; } public void testMathService() throws Exception { MuleClient client = new MuleClient(); MuleMessage msg = new DefaultMuleMessage(new Integer(5), (Map)null); MuleMessage result = client.send("vm://math", new Integer(5), null); System.out.println("Resultaat: " + result.getPayloadAsString()); assertEquals("-25", result.getPayloadAsString()); } }
Now we can clean and build the project with
mvn clean install
However the build failed because the test failed!
Problem was that the result of the unit test didn’t match the result I expected nor what was expected in the book! Of course, this wasn’t a good thing in this phase of the evaluation. I mean, the first example I try leads to unexpected results. But this was a good opportunity to test another aspect of the Mule ESB. I posted my situation on the Mule mailinglist to find out if the community behind the product still alive and active.
Well, in one word: yes, it is! Within a few hours I had the answer to my problem and within one day the answer was extended with some more background info why the showed behaviour differs from the one that was described in the book.
Now, these kind of things gives me confidence about the product, so I will definitely continue with the evaluation because I still believe the ‘tool’ can be of great value in our solution.
About the issue: it appears that Mule has changed the default value for the parameter ‘defaultSynchronousEndpoints’ from ‘true’ to ‘false’ in a later version of Mule. So in my case I had to add synchronous="true"
to each endpoint or set the value of ‘defaultSynchronousEndpoints’ to ‘true’.