ESB configuration language is a very powerful and robust way of driving enterprise data/messages through ESB mediation engine. However your requirements can become such that very large amount of configuration files in the form of sequences, endpoints ,proxies and transformations would be required to satisfy all the mediation requirements of your system. In such cases number of configuration files will be scattered all over and would be extremely hard to manage. What would be frustrating to note is that , most of the configurations of particular types are redundant in nature.
ESB Templates try to minimize this redundancy by creating prototypes that users can re-use and utilize as and when needed. This is very much analogous to classes and instances of classes where-as, a template is a class that can be used to wield instance objects such as templates and endpoints. Thus ESB Templates is an ideal way to improve re-usability and readability of ESB configurations/xml s. Addition to that users can utilize predefined Templates that reflect commonly used EIP patterns for rapid development of ESB message/mediation flows.
ESB templates comes in two different forms.
This defines a templated form of a ESB sequence. Sequence Template has the ability to parameterize xpath expressions used within a sequence defined inside a template. We invoke a Sequence Template with a mediator named call-template by passing parameter values ie:-
<call-template target=”template” > <parameter name=”name” value=”value”/> ..... </call-template>
Defines a templated form of an endpoint. Endpoint Template has the ability to parameterize a endpoint defined within it. Invoking a template of this kind is achieved using a template Endpoint ie:-
<endpoint template=”name” ...> <parameter name=”name” value=”value”/> ..... </endpoint>
Template is a parametrized sequence defined in ESB. Parameters of a template are defined in the form of xpath statement/s. Callers can invoke such a template by populating parameters with static values /xpath expressions . We call such an artifact, Call-Template mediator.
In other words template sequence is an abstract/generic form of a ESB sequence. Only a call template mediator can make a sequence template in to a concrete sequence. Let's illustrate this with a simple example. Suppose we have a sequence which logs hello world in four different languages. You would do that in ESB in following way,
<sequence> <switch source="//m0:greeting/m0:lang" xmlns:m0="http://services.samples"> <case regex="EN"> <log level="custom"> <property name=”GREETING_MESSAGE” value=”HELLO WORLD!!!!!!” /> </log> </case> <case regex="FR"> <log level="custom"> <property name=”GREETING_MESSAGE” value=”Bonjour tout le monde!!!!!!” /> </log> </case> <case regex="IT"> <log level="custom"> <property name=”GREETING_MESSAGE” value=”Ciao a tutti!!!!!!!” /> </log> </case> <case regex="JPN"> <log level="custom"> <property name=”GREETING_MESSAGE” value=”ハローワールド!!!!!!!” /> </log> </case> </switch> </sequence>
Instead of printing our hello world message for each and every language inside the sequence, we can create a generalized template of this actions which will accept any greeting message(from a particular language) and log it on screen. For example we can create the following template, which you may name "HelloWorld_Logger".
<template name="HelloWorld_Logger"> <parameter name="message"/> <sequence> <log level="custom"> <property name=”GREETING_MESSAGE” expression=”$func:message” /> </log> </sequence> </template>
With our "HelloWorld_Logger" in place, call-template mediator can populate this template with actual hello world messages and execute the sequence of actions defined within the template like with any other sequence. This is illustrated below
<sequence> <switch source="//m0:greeting/m0:lang" xmlns:m0="http://services.samples"> <case regex="EN"> <call-template target="HelloWorld_Logger"> <with-param name="message" value="HELLO WORLD!!!!!!" /> </call-template> </case> <case regex="FR"> <call-template target="HelloWorld_Logger"> <with-param name="message" value="Bonjour tout le monde!!!!!!" /> </call-template> </case> <case regex="IT"> <call-template target="HelloWorld_Logger"> <with-param name="message" value="Ciao a tutti!!!!!!!" /> </call-template> </case> <case regex="JPN"> <call-template target="HelloWorld_Logger"> <with-param name="message" value="ハローワールド!!!!!!!" /> </call-template> </case> </switch> </sequence>
Note how call template mediator/s point to the same template "HelloWorld_Logger" and pass different arguments to it. This way sequence templates make it easy to stereotype different workflows inside ESB.
<template name="string"> <!-- parameters this sequence template will be supporting --> ( <parameter name="string"/> ) * <!--this is the in-line sequence of the template --> <sequence> mediator+ </sequence> </template>
sequence template is a top level element defined with the name attribute in ESB configuration. Both endpoint and sequence template starts with a template element. Parameters (ie:-<parameter>) are the inputs supported by this sequence template . These sequence template parameters can be referred by a xpath expression defined inside the in-line sequence. For example parameter named 'foo' can be referred by a property mediator (defined inside the in-line sequence of the template) in following ways
<property name=”fooValue” expression=”$func:foo” />
OR
<property name=”fooValue” expression=”get-property('foo','func')” />
Note the scope variable used in the xpath expression. We use function scope or ?func? to refer to template parameters. Only through this parameter name, we can refer to a particular parameter value passed externally by a invoker such as call- template mediator. WSO2 Management console UI provide easy way of adding these parameters. An example is shown below.
Figure 1: Defining/Accessing Seqeunce Template Parameters
<call-template target="string"> <!-- parameter values will be passed on to a sequence template --> ( <!--passing plain static values --> <with-param name="string" value="string" /> | <!--passing xpath expressions --> <with-param name="string" value="{string}" /> | <!--passing dynamic xpath expressions where values will be compiled dynamically--> <with-param name="string" value="{{string}}" /> | ) * <!--this is the in-line sequence of the template --> </call-template>
call-template mediator should define a target template it should be invoking , with 'target' attribute.
<with-param> element is used to parse parameter values to a target sequence template. Note that parameter names has to be exact match to the names specified in target template. Parameter element can contain three types of parameterized values. xpath values are passed in within curly braces (ie:- {}) for value attribute. Special type of xpath expressions can be declared in double curly braces. These xpath expressions will be evaluated dynamically (others are evaluated before invoking a template or outside the template ) .
Please note that this is currently only supported for special type of mediators such as iterator and aggregate mediator, where actual xpath operations are made on a different soap message than the message coming in to the mediator. Following shows how users can declare parameters inside call-template mediator UI
Figure 2: Passing Values with Call Template Mediator
Endpoint Template is a generalized form of endpoint configuration used in ESB. Unlike sequence templates , endpoint templates are always parameterized using '$' prefixed values (ie:- NOT xpath expressions).
Template Endpoint is the artifact that makes a template of endpoint type into a concrete endpoint. In other words an endpoint template would be useless without a Template Endpoint referring to it. This is semantically similar to the relationship between a Sequence template and a Call-template mediator. For example lets say we have two default endpoints with following hypothetical configurations,
<endpoint name="ep1"> <default> <suspendOnFailure> <errorCodes>10001,10002</errorCodes> <progressionFactor>1.0</progressionFactor> </suspendOnFailure> <markForSuspension> <retriesBeforeSuspension>5</retriesBeforeSuspension> <retryDelay>0</retryDelay> </markForSuspension> </default> </endpoint> <endpoint name="ep2"> <default> <suspendOnFailure> <errorCodes>10001,10003</errorCodes> <progressionFactor>2.0</progressionFactor> </suspendOnFailure> <markForSuspension> <retriesBeforeSuspension>3</retriesBeforeSuspension> <retryDelay>0</retryDelay> </markForSuspension> </default> </endpoint>
We can see that these two endpoints have different set of error codes and different progression factors for suspension. Futhermore number of retries are different between them. By defining a endpoint template we can converge these two endpoints to a generalized form. This is illustrated in the follwoing (Note how '$' is used to paramaeterize configuration and $name is a implicit/default parameter) ,
<template name="ep_template"> <parameter name="codes"/> <parameter name="factor"/> <parameter name="retries"/> <endpoint name="$name"> <default> <suspendOnFailure> <errorCodes>$codes</errorCodes> <progressionFactor>$factor</progressionFactor> </suspendOnFailure> <markForSuspension> <retriesBeforeSuspension>$retries</retriesBeforeSuspension> <retryDelay>0</retryDelay> </markForSuspension> </default> </endpoint> </template>
Since we have a template defined we can use template endpoints to create two concrete endpoint instances with different parameter values for this scenario. This is shown below.
<endpoint name="ep1" template="ep_template"> <parameter name="codes" value="10001,10002" /> <parameter name="factor" value="1.0" /> <parameter name="retries" value="5" /> </endpoint> <endpoint name="ep2" template="ep_template"> <parameter name="codes" value="10001,10003" /> <parameter name="factor" value="2.0" /> <parameter name="retries" value="3" /> </endpoint>
As with call-template mediator , above template endpoint will stereotype endpoints with customized configuration parameters. This makes it very easy to understand and maintain certain ESB configurations and improves reusability in a certain way.
<template name="string"> <!-- parameters this endpoint template will be supporting --> ( <parameter name="string"/> ) * <!--this is the in-line endpoint of the template --> <endpoint [name="string"] > address-endpoint | default-endpoint | wsdl-endpoint | load-balanced- endpoint | fail-over-endpoint </endpoint> </template>
Similar to sequence templates ,endpoint templates are defined as top level element (with the name specified by the name attribute )of ESB configuration Parameters (ie:-<parameter>) are the inputs supported by this endpoint template . These endpoint template parameters can be referred by $ prefixed parameter name. For example parameter named 'foo' can be referred by $foo. Most of the parameters of the endpoint definition can be parametrized with $ prefixed values. This is shown in the following extract,
<template name="sample_ep_template"> <parameter name="foo"/> <parameter name="bar"/> <default> <suspendOnFailure> <errorCodes>$foo</errorCodes> <progressionFactor>$bar</progressionFactor> </suspendOnFailure> <markForSuspension> <retriesBeforeSuspension>0</retriesBeforeSuspension> <retryDelay>0</retryDelay> </markForSuspension> </default> </endpoint> </template>
Note $name and $uri are default parameters that a template can use anywhere within the endpoint template (usually used as parameters for endpoint name and address attributes). Following figure shows, how a endpoint template design page is rendered in WSO2 Management console UI.
Figure 3: Designing an Endpoint Template
<endpoint [name="string"] [key="string"] template="string"> <!-- parameter values will be passed on to a endpoint template --> ( <parameter name="string" value="string" /> ) * </endpoint>
Template endpoint defines parameter values that can parameterize endpoint . The 'template' attribute points to a target endpoint template.
As in the endpoint template , Note that parameter names has to be exact match to the names specified in target endpoint template. UI for a template endpoint is depicted below
Figure 4: Template Endpoint UI