Introduction
Inspiration for this post was problem I found in StackOverflow. It is about getting access to Properties set in Message Context in WSO2 Enterprise Integrator / WSO2 ESB. Of course I gave the appropriate answer. The first time I was thinking, that we can only do that by using Custom class mediator, as someone suggest. But there is a much simpler way to do that.
Solution
Some time ago i discover, that Script mediator in WSO2 EI, can run not only JavaScript code, but also code written in Java. Of course with some limitations. But it is much easier and faster way, than implement custom mediator for only that purpose. Using script mediator we cane get access to different types of Message Context, depend of what language/engine we chose. For JavaScript it is CommonScriptMessageContext, and from WSO2 EI 6.2.0 , you can additionally use Nashorn and it will be NashornJavaScriptMessageContext. In older WSO2 ESB 4.9.0 you can use only Javascript engine – but I tested that code. It will works in the same way.
<script language="js"><![CDATA[var keySet = mc.getPropertyKeySet();
var i = 1;
var it = keySet.iterator();
var propertySet = "\n\r";
while(it.hasNext()){
var prop = it.next();
propertySet += (i + ": " + prop + " = " + mc.getProperty(prop)+java.lang.System.lineSeparator());
i++;
}
mc.setProperty('propertySet',propertySet.toString());]]>
</script>
<log level="custom">
<property expression="$ctx:propertySet" name="propertySet" xmlns:ns="http://org.apache.synapse/xsd"/>
</log>
Yes, and that is all you need to do in your mediation path. In the log, you will get printed all the properties that are stored in message context. I create simple rest API for tests:
<api xmlns="http://ws.apache.org/ns/synapse" name="ApiForTests" context="/testing/scriptmediator">
<resource methods="POST GET">
<inSequence>
<property name="TestStringProperty" value="Some text in property" scope="default" type="STRING"/>
<property name="TestOMProperty" scope="default">
<testOm xmlns="">SomeValueInOmProperty</testOm>
</property>
<property name="TestFloatProperty" value="3.1415" scope="default" type="FLOAT"/>
<script language="js">
var keySet = mc.getPropertyKeySet();
var it = keySet.iterator();
var propertySet = "\n\r";
var i = 1;
while(it.hasNext()){
var prop = it.next();
propertySet +=(i + ": " + prop + " = " + mc.getProperty(prop)+java.lang.System.lineSeparator()); i++;
}
</script>
<log level="custom">
<property expression="$ctx:propertySet" name="propertySet" xmlns:ns="http://org.apache.synapse/xsd"/>
</log>
<respond/>
</inSequence>
</resource>
</api>
With some three custom properties in mediation: TestStringProperty, TestOMProperty, TestFloatProperty and after API call, in log I got:
Extra hint
Because it is quite useful trick, I suggest you to store this code in a separate file, referenced via the Local or Remote Registry entry. After that you can easily use a key to refer to a script, which is already saved in the Registry and reuse it, as documentation describes here.
Summary
The Script mediator is very handy, and give much more than documentation describes. If you know, how to write code in Java it becomes quite a powerful tool. If you know Anther plus is that, you can apply all our ideas “on the fly”, without restarting WSO2 for reload libraries with custom class mediator.