Script Mediator¶
The Script Mediator is used to invoke the functions of a variety of scripting languages such as JavaScript, Groovy, or Ruby.
A Script mediator can be created using one of the following methods.
- With the script program statements stored in a separate file, referenced via the Local or Remote Registry entry.
- With the script program statements embedded inline within the Synapse configuration.
Synapse uses the Apache Bean Scripting Framework for scripting language support.
Any script language supported by BSF may be used to implement the Synapse Mediator. With the Script Mediator, you can invoke a function in the corresponding script. With these functions, it is possible to access the Synapse predefined in a script variable named mc
.
The mc
variable represents an implementation of the MessageContext
, named ScriptMessageContext.java
, which contains the following methods that can be accessed within the script as mc.methodName
.
Return? | Method Name | Description |
---|---|---|
Yes | getPayloadXML() | This gets an XML representation of SOAP Body payload. |
No | setPayloadXML(payload) | This sets the SOAP body payload from XML. |
No | addHeader(mustUnderstand, content) | This adds a new SOAP header to the message. |
Yes | getEnvelopeXML() | This gets the XML representation of the complete SOAP envelope. |
No | setTo(reference) | This is used to set the value which specifies the receiver of the message. |
Yes | setFaultTo(reference) | This is used to set the value which specifies the receiver of the faults relating to the message. |
No | setFrom(reference) | This is used to set the value which specifies the sender of the message. |
No | setReplyTo(reference) | This is used to set the value which specifies the receiver of the replies to the message. |
Yes | getPayloadJSON() | This gets the JSON representation of a SOAP Body payload. |
No | setPayloadJSON( payload ) | This sets the JSON representation of a payload obtained via the getPayloadJSON() method and sets it in the current message context. |
Yes | getProperty(name) | This gets a property from the current message context. |
No | setProperty(key, value) | This is used to set a property in the current message context. The previously set property values are replaced by this method. |
Implementing a Mediator with a script language has advantages over using
the built-in Synapse Mediator types or implementing a custom Java class
Mediator. The Script Mediators have the flexibility of a class Mediator
with access to the Synapse MessageContext
and
SynapseEnvironment
APIs. Also, the ease of use and
dynamic nature of scripting languages allow the rapid development and
prototyping of custom mediators. An additional benefit of some scripting
languages is that they have very simple and elegant XML manipulation
capabilities, which make them very usable in a Synapse mediation
environment. e.g., JavaScript E4X with RhinoJS or Ruby REXML.
For both types of script mediator definitions, the
MessageContext
passed into the script has additional
methods over the standard Synapse MessageContext
to
enable working with XML natural to the scripting language. Example are
when using JavaScript getPayloadXML
and
setPayloadXML
, E4X
XML objects
and when using Ruby, REXML documents.
Limitations and Alternatives to Script Mediator
While the Script mediator offers enhanced extensibility in the Synapse configuration, it is important to consider its potential limitations. We highly recommend utilizing the Script mediator only when absolutely necessary. In cases where extension requirements can be fulfilled using alternatives such as the Class mediator, we advise opting for the latter due to several reasons. Notably, the use of a Script mediator in moderately complex to sophisticated mediation flows may introduce significant performance overhead compared to a Java-based Class mediator. Therefore, we suggest prioritizing Class mediators as extensions to the mediation flow over Script mediators. However, for simpler tasks, the Script mediator can still serve as a versatile option.
Note
The Micro Integrator uses GraalVM JS by default. If you have specified the language as rhinoJs
, Rhino engine will be used to execute JavaScript. Rhino engine converts the script to a method inside a Java class. Therefore, when processing large JSON data volumes, the code length must be less than 65,536 characters, since the Script mediator converts the payload into a Java object. However, you can use the following alternative options to process large JSON data volumes.
- Achieve the same functionality via a Class mediator.
- If the original message consists of repetitive sections, you can use the Iterate mediator to generate a relatively small payload using those repetitive sections. This will then allow you to use the Script mediator.
- The Script Mediator supports using the default GraalVM JS to execute JavaScript.
Prerequisites¶
-
Listed below are the prerequisites for writing a Script mediator using JavaScript, Groovy, or Ruby.
Scripting Language Prerequisite Groovy Download the groovy-all -2.4.4.jar
file and copy it to the<MI_HOME>/
dropins directory. Note that when you define the script, you need to start by importing Groovy.Ruby Install the JRuby engine for mediation. This is available in the WSO2 P2 repository as a feature (WSO2 Carbon - JRuby Engine for Mediation).
Alternatively, you can download and install the JRuby engine manually: Download the
jruby-complete-1.3.0.wso2v1.jar
file from the WSO2 P2 repository and copy it to the<MI_HOME>/
dropins directory.JavaScript The JavaScript based on GraalVM JS is enabled by default in the Micro Integrator and ready for use. Note
The
nashornJs
language is deprecated in JDK 15 and above. If you are using JDK 15 or above, you need to manually copy the nashorn-core and asm-util JAR files to the<MI_HOME>/lib
directory since Nashorn was removed from the JDK.
Syntax¶
Click on the relevant tab to view the syntax for a script mediator using an Inline script, or a script mediator using a script of a registry
- Using an Inline script:
The following syntax applies when you create a Script mediator with the script program statements embedded inline within the Synapse configuration.
<script language="js"><![CDATA[...script source code...]]></script>
-
Using a script of the registry: The following syntax applies when you create a Script mediator with the script program statements stored in a separate file, referenced via the Local or Remote Registry entry.
Info
If you are creating the Registry Resource via Tooling, you need not specify the content/media type, because it gets automatically applied when you select the JavaScript File Template.
<script key="string" language="js" [function="script-function-name"]> <include key="string"/> </script>
Configuration¶
-
Inline: If this script type is selected, the script is specified inline. The parameters available to configure a Script mediator using an inline script are as follows.
Parameter Name Description Language The scripting language for the Script mediator. You can select from the following available languages.
- JavaScript - This is represented as
js
in the source view. - Groovy - This is represented as
groovy
in the source view. - Ruby - This is represented as
rb
in the source view.
Source - JavaScript - This is represented as
-
Registry: If this script type is selected, a script which is already saved in the registry will be referred using a key. The parameters available to configure a Script mediator using a script saved in the registry are as follows.
Parameter Name Description Language The scripting language for the Script mediator. You can select from the following available languages.
- JavaScript - This is represented as
js
in the source view. -
Groovy - This is represented as
groovy
in the source view. Note: Be sure that your script starts with the following, which indicates that Groovy is imported: - Ruby - This is represented as
rb
in the source view.
Function The function of the selected script language to be invoked. This is an optional parameter. If no value is specified, a default function named mediate
will be applied. This function considers the Synapse MessageContext as a single parameter. The function may return a boolean. If it does not, then the valuetrue
is assumed and the Script mediator returns this value.Key Type You can select one of the following options.
- Static Key : If this is selected, an existing key can be selected from the registry for the Key parameter.
- Dynamic Key : If this is selected, the key can be entered dynamically in the Key parameter.
Key The Registry location of the source. You can click either Configuration Registry or the Governance Registry to select the source from the resource tree. Include keys This parameter allows you to include functions defined in two or more scripts your Script mediator configuration. After pointing to one script in the Key parameter, you can click Add Include Key to add the function in another script.
When you click Add Include Key , the following parameters will be displayed. Enter the script to be included in the Key parameter by clicking either Configuration Registry or the Governance Registry and then selecting the relevant script from the resource tree.
- JavaScript - This is represented as
Note
The Script mediator now utilizes the GraalVM JS engine for the js
language. The GraalVM JS engine does not provide E4X support for XML. For E4X support, you can use the Rhino engine. To use the Rhino engine, you need to specify the language as rhinoJs
in the Script mediator language configuration.
Examples¶
Use an inline script¶
The following configuration is an example of an inline mediator using JavaScript/E4X
which returns false if the SOAP message body contains an element named symbol
, which has a value of IBM
.
<script language="js"><![CDATA[mc.getPayloadXML()..symbol != "IBM";]]></script>
Use a script saved in the registry¶
In the following example, script is loaded from the registry by using the key repository/conf/sample/resources/script/test.js
.
<script language="js"
key="repository/conf/sample/resources/script/test.js"
function="testFunction"/>
script language="js"
indicates that the function invoked should be in the JavaScript language. The function named testFunction which is invoked should be saved as a resource in the Registry.
The script can be as shown in the example below.
function testFunction(mc) {
var symbol = mc.getPayloadXML()..*::Code.toString();
mc.setPayloadXML(
<m:getQuote xmlns:m="http://services.samples/xsd">
<m:request>
<m:symbol>{symbol}</m:symbol>
</m:request>
</m:getQuote>);
}
Add an include key¶
The following configuration has an include key
.
<script language="js" key="stockquoteScript" function="transformRequest">
<include key="sampleScript"/>
</script>
The script is written in JavaScript. The function to be executed is transformRequest
. This function may be as follows in a script saved in the Registry.
// stockquoteTransform.js
function transformRequest(mc) {
transformRequestFunction(mc);
}
function transformResponse(mc) {
transformResponseFunction(mc);
}
In addition, the function in the script named
sampleScript
which is included in the mediation
configuration via the include key
sub element is also
executed in the mediation. Note that in order to do this,
sampleScript
script should also be saved as a
resource in the Registry . This script can be as follows.
// sample.js
function transformRequestFunction(mc) {
var symbol = mc.getPayloadXML()..*::Code.toString();
mc.setPayloadXML(
<m:getquote m="http://services.samples">
<m:request>
<m:symbol>{symbol}</m:symbol>
</m:request>
</m:getquote>);
}
function transformResponse(mc) {
var symbol = mc.getPayloadXML()..*::symbol.toString();
var price = mc.getPayloadXML()..*::last.toString();
mc.setPayloadXML(
<m:checkpriceresponse m="http://services.samples/xsd">
<m:code>{symbol}</m:code>
<m:price>{price}</m:price>
</m:checkpriceresponse>);
}
Add a custom SOAP header¶
You can add custom SOAP headers to a request by using the addHeader(mustUnderstand, content)
of the Script mediator in a proxy service as shown in the example below.
<?xml version="1.0" encoding="UTF-8"?>
<proxy name="CustomSOAPHeaderProxy" startOnLoad="true" transports="http https" xmlns="http://ws.apache.org/ns/synapse">
<target>
<inSequence>
<log category="INFO" level="full">
<property name="Message" value="IncomingRequest"/>
</log>
<script description="javascript scripts" language="js"><![CDATA[mc.addHeader(false, <ns:sampleCustomHeader xmlns:ns="gsb:http://wso2.org/sample"><ns:customInfo>CustomHeader</ns:customInfo></ns:sampleCustomHeader>);]]></script>
<log category="INFO" level="full">
<property name="Message" value="UpdatedMessage"/>
</log>
<drop/>
</inSequence>
<faultSequence/>
</target>
</proxy>
Example per method¶
The following table contains examples of how some of the commonly used methods can be included in the script invoked by the following sample Script mediator configuration.
<script language="js"
key="conf:/repository/EI/transform.js"
function="transform"/>
Return? | Method Name | Example |
---|---|---|
Yes | getPayloadXML() | The script invoked can be as follows.
|
No | setPayloadXML(payload) | See the example above for the getPayloadXML() method. mc.setPayloadXML( <m:getquote m="http://services.samples"> <m:request> <m:symbol>{symbol}</m:symbol </m:request> </m:getquote> ) is used in that script to set the XML representation of the SOAP body (obtained using the getPayloadXML() method) to the current message context. |
No | addHeader(mustUnderstand, Object content) | The script invoked can be as follows.
The
|
No | getEnvelopeXML() | The script invoked can be as follows.
|
Yes | getPayloadJSON() | The script invoked can be as follows.
|
No | setPayloadJSON(payload) | See the example script for the The |
Yes | getProperty (name) | The script invoked can be as follows. In this example, the |
No | setProperty(property) | See the example for the In the following example, var result = "a" and then result = result + "b" . When concatenating these strings, the script invoked needs to be as follows:
|