Polyglot programming in Mule: Scripting pack now part of the distribution

motif

Sometimes when transforming complex data structures or applying business rules to your integration, you may face the need to add some custom code. We make our best effort to try to productize and solve every common use case we come across, but sometimes it’s just not enough. When that happens, you probably turn to the programming language you love the most for help. If you’re a Java guy, you can build your own custom components and/or transformers inside . If you’re into .NET, we recently released our .NET integration framework. We also have something we call the pack” which enables the use of scripting languages such as , Javascript, Python or Ruby inside your flows. For Mule 3.6, we decided to give it a big upgrade!

Give the pack some love

Before Mule 3.6, the community distribution of the Mule only included Groovy. Although you could download it separately, Jython, Javascript and JRuby only came bundled by default on the Enterprise distribution. Now we decided to make that experience better for our users by:

  • Including all 4 scripting languages by default in the community distribution
  • We upgraded Groovy and Jython to versions 2.3.7-indy and 2.7.3B3, which are the latest available at the moment of the 3.6 release
  • We switched to Rhino as our default implementation for Javascript, using version 1.7R4 which is also the latest.

Is Mule limited to only these four scripting languages? No! Any language supporting JSR-223 will be discovered an available to use.

Performance boost through invoke dynamic

In JDK7, a new byte code instruction called “invoke dynamic” was added to allow scripting languages to have a big performance improvement. Starting with version 3.6, JDK7 is now the minimum required JDK to run Mule which means that we can now take advantage of that Java feature. The Groovy and Jython versions that are now added to the distributions take advantage of this which means that you will see a speed boost in your groovy and python scripts!

Seamless integration with Mule

No matter which scripting language you’re using, Mule will automatically bind some variables into your so that you can interact with mule. Those properties are:

loga logger that can be used to write to Mule’s log file.
muleContexta reference to the MuleContext object.
eventContextA reference to the EventContext. This allows you to dispatch events programmatically from your script
messagethe current message.
originalPayloadthe payload of the current message before any transforms.
payloadthe transformed payload of the current message if a transformer is configured on the service. Otherwise this is the same value as originalPayload.
srcsame as payload, kept for backward compatibility.
servicea reference to the current service object.
idthe current event id.
resulta placeholder object where the result of the script can be written to. Usually it’s better to just return a value from the script unless the script method doesn’t have a return value.

 

An example

Let’s see an example of how to implement a flow which uses the “Greedy Coin Changer” algorithm. This is actually an example that ships with the Mule distribution. Below I’ll show a simplification of it, you can see the full example following this link.

This is the flow configuration:

Could not embed GitHub Gist 6ff292e44ab4ce5123dc: Bad credentials. The API can't be accessed using username/password authentication. Please create a personal access token to access this endpoint: http://github.com/settings/tokens

In the above flow we see a flow which starts with a http inbound endpoint. It uses some transformers to transform the input data and then applies the algorithm, using Groovy if the currency is US Dollars or Python in the case of British pounds. This is the groovy implementation of the algorithm:

Could not embed GitHub Gist 3cae5aee6f2af7cd0f10: Bad credentials. The API can't be accessed using username/password authentication. Please create a personal access token to access this endpoint: http://github.com/settings/tokens
And this is the Python one:
Could not embed GitHub Gist 6e2033f2e9eaf5c8dedd: Bad credentials. The API can't be accessed using username/password authentication. Please create a personal access token to access this endpoint: http://github.com/settings/tokens

Using transformers

The use of scripting languages is not limited to components, you can also use if for transformations:

Could not embed GitHub Gist d7c91cfea53e044abf12: Bad credentials. The API can't be accessed using username/password authentication. Please create a personal access token to access this endpoint: http://github.com/settings/tokens

As you can see, the groovy is bounded to the message payload through the ‘payload’ variable (although message.getPayload() would have done it as well). But is for simplicity reasons you want to pass your own parameters, you can do that as well!

Could not embed GitHub Gist d4658231258bdce19d38: Bad credentials. The API can't be accessed using username/password authentication. Please create a personal access token to access this endpoint: http://github.com/settings/tokens

Take aways

We’re now bundling Groovy, Javascript, Python and Ruby scripting languages on the CE distribution. You can also add any JSR-223 compliant language to your application. Happy scripting!


We'd love to hear your opinion on this post