Blog

October 21, 2013

Integration Software Is Software

There seems to be a lack of emphasis on professional software development practices in the Mule ESB developer community.  This is probably not exclusive to Mule; the exposure I’ve had to competing platforms has been no different.  Since integration’s role in enterprise software systems is so critical, I would expect people to take their time to get it right.

Certain software methods are commonplace, at least with the java and .NET teams I’ve worked with.  These same methods are rarely practiced by Mule application developers. I have an idea why:

Discipline Doesn’t Sell

I recently attended the Mule Summit in Denver, where I saw several cool product demonstrations. They went something like this:

  1. In Mule Studio, drag and drop some components onto the palette
  2. Double click to configure the components
  3. Run your Mule Application
  4. Manually trigger the flow (create a file, access a web page, etc.)

The online examples also seem to promote a code – poke – deploy development process:

Follow the procedure below to create, then run the HTTP Request-Response with Logger application in Mule ESB.

  1. Create, then run the example application in Mule Studio.
  2. Open your Web browser, type http://localhost:8084/echo in the address bar, then press enter.
  3. Your browser presents a message that reads, /echo.
  4. In your browser’s address bar, replace the word echo with the word moon, then press enter.
  5. Your browser presents a message that reads, /moon.

from HTTP Request-Response with Logger Example

This development experience is strikingly different from our normal workflow.

The Confluex Way

Well let me set the record straight: Mule application development is software development. And it works better when you consistently apply a few practices:

Test Driven Development

The reasons to do TDD have been explained eloquently by smarter people than me.  But, like George, I do it because it makes me better at what I do. Learning to do TDD well is like learning to touch type, and you will slow down before you speed up. Unfortunately, Mule applications are more difficult to test than plain old java code.  You have to write them in java, you often have to get crafty with spring, and you have to spend considerable effort to create mocks or stubs for all the systems you’re integrating with.  Even with all this additional effort, I build good software faster this way.  I also find that the more I do it, the easier it gets.   Mulesoft is planning to release munit to help make testing Mule applications easier. We’ve also released a couple libraries to help mock external systems, like web services and salesforce.com’s APIs.

Refactoring

Once your tests pass, it’s time to refactor.  That means improving your working code without adding any new behavior.  I refactor after I get each test to pass, and it usually takes somewhat less time than writing the test and the code.

Single Responsibility Principle

In Mule, we have several “units” of code.  Applications have mule configuration files.  Configuration files have flows, sub-flows, and global elements.  Each unit should do one thing, and do it well.  If you have to scroll horizontally in Mule Studio, perhaps you need a sub-flow.  If you have to scroll a lot to find a sub-flow you want to change, perhaps it’s time to split your configuration file.  If you find yourself wanting to organize your configuration files better, maybe pull some of them out into their own Mule application.

Always make these decisions based on a unit’s purpose.  If it’s hard to pin down what a unit is “for”, think about splitting it up.

Logging

Your application’s log file is often the primary means to communicate about its status to production support.  It’s fairly simple to use log4j to accomplish this.  In your logger message processors, use consistent category names with appropriate levels and meaningful messages to report your application’s activity to the support team.

You can use appenders to redirect certain categories to other files, and turn off additivity if you want to keep the console output concise.  I suggest muting most of Mule’s internal logging, but leaving DefaultMuleContext at INFO so you can see when your application has started.

Clean Mule Code

It is not enough to write the code well.  The code has to be kept clean over time.  We’ve all seen code rot and degrade as time passes.  So we must take an active role in preventing this degradation.

Uncle Bob Martin in Clean Code

Formatting matters.  Naming matters.  Consistency matters.  Take the time to clean up both the XML and the Flow Editor views of your Mule applications.  Refactor your junit tests a bit, and extract useful bits into libraries.

Look for ways to use Mule’s built-in message processors and routing, rather than creating your own java or groovy components. Also look for places where over-complicated Mule flow code can be done better with a java or groovy component.

Build Automation

Mule Studio has a feature that allows developers to Export from Mule Studio directly to the MMC repository, CloudHub, or to a Deployable Archive. Mulesoft should just remove that feature. Long ago, a sysadmin I admired told me about his Rule of Three: once he realized he was repeating a manual process, he made a mental note.  If he found himself doing it a third time, he wrote a script.  Someone like him started tools like Ant, Maven and Gradle.  Automating things makes certain accidents impossible.  It keeps you from forgetting a step.  Anybody on the team can do it, and it will be done exactly the same way.

Mule has fairly good Maven integration, both directly and through Mule Studio.  Unless you have good reason to go with Ant or Gradle, we recommend using Maven automation for every project.

Source Control

Just check your code in.  Even if you’re sure you’re going to write it today, run it once, and then never use it again. It’s easy and free to install git and make a repository in the cloud. And a source control repository never forgets anything, which I suspect is not true for most programmers.  Old code has a way of becoming useful right after you deleted it.  Source control is a time machine for code.  And as soon as you want someone else to help out, you just send them a link, and you can both edit it at the same time.

External Configuration

Mule source code is written in XML files, which are unfortunately called “configuration files”.  This is not where configuration settings like web service URLs and database credentials belong.  Use Spring’s property placeholder to pull these settings in from properties files on the classpath and the server’s filesystem.  Spring will load properties from each resource in turn, overriding properties when it finds them more than once.  This allows you to provide default values for properties, and customize them per environment.

The MULE_ENV property used here must be set in the java virtual machine when Mule starts.  You can do this in conf/wrapper.conf, or when you start mule.

You might also look at Zuul, a more robust solution for securely delegating configuration management.

Conclusion

Quality is hard won and easily lost.  Luckily, it’s not an all-or-nothing goal.  Consistently apply moderate effort to create more professional software, and you will find that you can make working software that people need, when they need it.

By Ryan Hoegg Agile Mule ESB Testing Share:

5 thoughts on “Integration Software Is Software

  1. Mubashar Ali says:

    Hi Ryan,
    I am using Mule ESB with SugarCRM connector. I have seen some test example in Mule ESB basic tutorial to understand Mule ESB studio, how to work with Mule ESB using flows. Right now, I am facing difficulties to achieve my desire goal with SugarCRM and Mule ESB. On Mule ESB forum I don’t see any help available for this. I have lot of research, google etc but didn’t get any thing.

    Please if you have any idea OR help then share it with me to achieve my desire goal with Mule ESB and SugarCRM.

    Thanks for the help in advance.

  2. Grzegorz Poznachowski says:

    Great article! It’s good that somebody brought that up. What was kind of frustrating to me in the beginning (when I was exploring Mule for the first time) is there was almost no info about good practices (when handling Mule configuration files etc.)
    I also find writing Mule unit tests more challenging then plain Java ones. It takes some time to start ‘feeling it’. Most important and most difficult, in my opinion, is figuring out a good structure for your flows and files (vide Single Responsibility paragraph). When that’s tackled well, it’s getting much easier when it comes to testing.
    As of MUnit. We started using it in our project as soon as we discovered it. It really helps mocking out endpoints and even message processors. It still has some quirks and I’m missing some functionality, that would be helpful, but I would recommend give it a try. Unfortunately, it seems that MUnit development slowed down recently. I have a blog post about setting REST services on Mule, where tests are written in MUnit: http://poznachowski.blogspot.co.uk/2013/10/exposing-restful-interface-with-mule-pt1.html You come by and can check it out.

    1. Ryan Hoegg says:

      Good post Grzegorz, and I enjoyed the follow up about using the Jersey Module. I checked out your MUnit test on github, and it looks like it’s pretty good for gray-box and white-box testing of Mule flows.

      My preference is to make my tests black-box as much as I can; for example, calling a REST service using an HTTP client directly, or using an in-memory database with direct JDBC access from my test. I will give MUnit a whirl and see how well I can do black-box testing with it.

      Thanks for the comment!

  3. Adam Boltz says:

    Great post. It’s nice to see an experienced Mule user also saying that testing Mule is harder than a plain old Java app. I was unaware of munit — you say it’s not released yet, but is it mature enough to be useful already?

    1. Ryan Hoegg says:

      I have been keeping an eye on munit, but I still write all my tests with plain old junit and Mule’s FunctionalTestCase. Until I give it a real try, I hope another reader with more munit experience can answer.

Leave a Reply

Your email address will not be published. Required fields are marked *