Saturday, September 02, 2017

SOA 12c JavaScript: Shaken, not stirred

Have you ever faced XML/XPath limitations? I bet you have. Mostly it's related to the string manipulations. Parsing, complex replacements, regular expressions, array transformations, I don't even start about math or anything else, that every modern language has out of the box. In the Oracle SOA world, you are moaning and pull Java Embedded Activity to the process, every time when you need something like that.

Sure you could use Java string operations in XSLT but it means you should create XSLT document for that matter. SOA 12c is a game changer. With the native JSON support, it brings you JavaScript.
The question "Can I use JavaScript with my XML data?" has the answer: " Yes, You can!".

Let's take a look on the very simple composite: It takes a string as an input and returns word count. This implementation is far for perfect because counts only spaces and ignores everything else. The purpose is composite with no Java activities.
Request and response types are simple:
  • SimpleRequestType restricts standard xsd:string up to 60 characters
  • SampleResponseType returns integer numbers > 0. 
Composite exposes BPEL component as SOAP/XML web service using described types for the
request and response.  The BPEL itself is boring it literally has three  activities:

  • Receive activity receiveInput
  • Assign activity CountWords
  • Reply activity replyOutput.
Respectively, it has:

  • XML message inputVariable
  • XML message outputVariable,  
  • JSON string variable counter

I haven't found a way to make such assignment in one single operation, so it uses 2 copy activities and variable. If you know the shortcut, please let me know.

<assign name="CountWords">
 <copy>
  <from expressionLanguage="javascript">process.inputVariable.payload</from>
  <to expressionLanguage="javascript">process.counter</to>
 </copy>
 <copy>
  <from expressionLanguage="javascript">
                   process.counter.SimpleRequest.$.split(" ").length.toString()
                </from>
  <to expressionLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0">
                   $outputVariable.payload
                </to>
 </copy>
</assign>

Attribute expressionLanguage identifies the language for the expression and the most important you can mix and match them, check the second copy definition!  Ok, let's discuss both copy activities:

  1. From the past experience, you may think that the first command copies string content of the payload to the string object, but it's not. In fact, the first copy creates JSON representation of the SimpleRequest type and then assigns it to the counter object.  
  2. As soon as you have figured out how your JSON object looks like the second copy is simple. With the JS string methods split the string and count array elements could be done in one single spaghetti. The result goes straight to the output variable. 
You may wonder why I have converted integer attribute .length to the string representation. Well, it's is the easiest way to handle JSON numbers to xsd:int.  Internal JSON-XML translator converts integer object into decimal numbers but correctly assigns string values. 


It's time for test and for the last picture (oh boy, I love it!).  The process does exactly what we need.
It converts XML to JSON, runs JavaScript and returns the result in one single activity.


Check the SOA documentation. You can use JavaScript as a default expression language for the BPEL process, make and assertions and execute JavaScript code the same way you run Java and it's cool. 



© Special thanks to Mark Rain for the thumbnail picture. 

No comments: