Sequence and Mediation Fragment

This section discuss the development of sequences and mediation logic to facilitate mediation of the messages coming into the proxy services.

Sequence and Mediation

A Sequence defines the mediation actions to be performed on a message. A Sequence may be defined in-line and locally to a proxy service, or defined as a re-usable sequence with an ID and referenced. A sequence maybe specified as a Java or JSR 223 script fragment, class or Spring bean, or a source file. Irrespective of the style of definition, each sequence executes as byte-code on the JVM.

Java and script sequences are exposed the current message by a special variable "msg", and the Mediation instance by the special variable"mediation". The interfaces Message and Mediation in the UltraESB API package allows one to perform almost anything within a sequence. However, one should be careful to not spawn new threads from within a sequence, as the UltraESB manages the execution threads which invokes sequences.

While the API documentation provides the complete reference of the operations available to use in mediation, the Mediation Reference describes those operations from the usage perspective, where it will be easy to map your requirement usage into the required API call and how to effectively call it.

To configure a sequence you need to add an element with the tag name "sequence" qualified with the UltraESB namespace. On your IDE, type angular bracket ("<") to see the available options on the ultra-unit.xml file of the deployment unit and select the sequence as shown below to add a sequence.

sequence add

Once you select the sequence and hit enter a bare sequence will be added with an "id" attribute. Fill the id attribute with "MyFirstSequence" to give the identifier for the sequence.

Starting the sequence configuration

<u:sequence id="MyFirstSequence">
  <!-- sequence type child element -->
</u:sequence>
Note
While a sequence that is referred is defined on the top level in the ultra-dynamic.xml with the "sequence" element tag name with an identifier an in-lined sequence of a proxy service will have the element tag name "inSequence","outSequence" or "errorSequence" depending on where it is placed in the proxy service.

Sequence Types

The UltraESB allows one to use multiple formats for specifying mediation steps within a sequence. The support ranges from Java code snippets specified as Java source code fragments, to any scripting language supported by JDK 7. All sequences specified as Java or scripting language source code is compiled and executed as byte code. This allows a user with extreme ease of use with his preferred language/s of choice, whilst allowing all code to run at compiled byte code speed with the full power of the JVM. It is also possible to only provide compiled sequences as Java classes, or even specify a Spring managed bean as a sequence. Although leaving mediation logic in configuration allows simpler management and version control, using compiled code may be preferred by certain other users concerned with security etc. and a hardened deployment model for configuration.

Sequence type is identified with the type of the child element used inside the sequence element. Unlike in endpoints there is no attribute defining the type as there are clearly different child elements for each and every sequence type.

To add a sequence type child element again type the angular bracket ("<") within the sequence element (this usually gets popped up just after specifying the identifier for the sequence too) and select the desired type from the popped up list of child elements as per the following description on each and every sequence types.

sequence types
A Java code snippet

A Java code snippet is the most easy way to mediate messages, and usually makes use of the utility methods exposed by the helper class 'Mediation'. Optionally, a snippet could specify any packages used by the code for import.

Sample Java code snippet sequence

<u:java import="java.io.*;"><![CDATA[
  String[][] ns = {{"soap", "http://soap.services.samples/"}};
  if (mediation.filter(msg, "//soap:getQuote/request/symbol", ns, "ADRT")) {
    mediation.sendToEndpoint(msg, "stockquote");
  } else {
    mediation.sendToEndpoint(msg, "stockquote-err");
  }
]]></u:java>
A script snippet sequence

A Script sequence could be written using any scripting language supported by Java JDK 7. A list of languages maybe found at [https://en.wikipedia.org/wiki/List_of_JVM_languages]. The UltraESB does not ship with optional libraries required to support these scripting languages, and the user is responsible for making these available to the runtime if required. However, the JDK ships with support for Javascript, which is available out of the box with the UltraESB.

Sample script snippet sequence

<u:script><![CDATA[
  var val = message.getMessageProperty("QUERY_STRING");
  val = val.replace('x', 'a');
  val = val.replace('y', 'b');
  val = val.replace('z', 'c');
  message.addMessageProperty("QUERY_STRING", val);
]]></u:script>
A script file

A script file sequence is similar to a script snippet sequence and is defined as follows.

Sample script file sequence

<u:scriptFile filename="test/resources/script_seq.js"/>

Where the file script_seq.js may contain the following

Script file

print("Message target : " + message.getDestinationURL());
if ("gold".equals(message.getFirstTransportHeader("ClientID"))) {
  mediation.sendToEndpoint(message, "test1");
} else {
  mediation.sendToEndpoint(message, "test2");
}
Byte code sequence

A Class that implements the public API interface 'JavaClassSequence' maybe specified as a byte code sequence. A byte code sequence is stateful and may persist information between successive calls as shown in the following example

Sample byte code sequence

<u:class name="org.adroitlogic.ultraesb.core.SampleByteCodeSequence"/>

Where the byte code is the class file compiled from the following source

Class file source of the sample byte code sequence

package org.adroitlogic.ultraesb.core;

import org.adroitlogic.ultraesb.api.JavaClassSequence;
import org.adroitlogic.ultraesb.api.Message;

public class SampleByteCodeSequence implements JavaClassSequence {
  private long startTime;
  private int count;

  public void execute(Message msg, Mediation mediation) throws Exception {
    System.out.println("Message target : " + msg.getDestinationURL());
    if ("gold".equals(msg.getFirstTransportHeader("ClientID"))) {
      org.adroitlogic.ultraesb.TestMediation.sendToEndpoint(msg, "test1", "responseSeqKey");
    } else {
      org.adroitlogic.ultraesb.TestMediation.sendToEndpoint(msg, "test2", "responseSeqKey");
    }
    count++;
  }

  public void init(Configuration config) {
    startTime = System.currentTimeMillis();
  }

  public void destroy() {
    System.out.println("Byte code sequence, Execution time : " + (System.currentTimeMillis() - startTime) +
      "ms. Processed : " + count + " messages");
  }
}
Java source file

It is also possible to specify the source code of a Java class as shown above as a Java source sequence. The UltraESB would simply compile the sequence at each startup.

Sample Java source file sequence

<u:javaFile filename="test/resources/java_seq.java"/>
Spring bean sequence

A Spring bean which implements the 'JavaClassSequence' interface maybe specified as a Spring bean sequence. For such a sequence one may use the Spring configuration to wire its dependencies, and simply inject this instance for mediation as shown in the example below.

Sample spring bean sequence

<u:sequence id="myseq7">
  <u:bean name="mybean"/>
</u:sequence>
...
<bean name="mybean" class="org.adroitlogic.ultraesb.core.SampleByteCodeSequence"/>
Support for other options and languages

The support for script based sequences effectively allows one to define a new language for configuration. Thus if required one can invent a new configuration language as a Java 6 scripting language, and it could even be an XML configuration language - for example.

Error Handling of Sequences

Error handlers for sequences are defined as a reference to another sequence via an attribute in the sequence element. Error handler is getting the message in case of an error while on the mediation of the defined sequence.

Configuring an error handler requires a referred sequence and that should be linked with the attribute named "onErrorInvoke" as follows.

Error handler configuration of sequence

<u:sequence id="MyFirstSequence" onErrorInvoke="MyErrorSequence">
  <!-- sequence definition -->
</u:sequence>

<u:sequence id="MyErrorSequence">
  <!-- error sequence definition -->
</u:sequence>
In this topic
In this topic
Contact Us