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:
- In Mule Studio, drag and drop some components onto the palette
- Double click to configure the components
- Run your Mule Application
- 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.
- Create, then run the example application in Mule Studio.
- Open your Web browser, type
http://localhost:8084/echoin the address bar, then press enter.
- Your browser presents a message that reads,
- In your browser’s address bar, replace the word
echowith the word
moon, then press enter.
- Your browser presents a message that reads,
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.
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.
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.
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.
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.
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.
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.
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.