An ESB can be deployed as a front end for various services with a very high load passing through it. The traffic passing through it may be of different priorities and can have different load charasterisitcs. Also in some situations load of different types of messages can vary dramatically over time.
The goal is to serve high priority traffic when there are resources available in the system regardless of the low priority traffic. The serving of different priority messages should be independent as much as possible. For example an ESB can be bombarded with very high volume of low priority traffic. Even in this case ESB should obey its contract to serve high priority traffic.
Usually a person deploying an ESB expects a certain guarantee of message deliverance from the ESB. ESB should be able to honor that.
Here is a possible scenario with a high volume of traffic.
Lets assume ESB is configured to serve two types of messages with different priorities. Message type m1 has the priority p1 and message type m2 has priority p2. p1 is about ten times the priority of p2. In a very high volume traffic scenario the services can afford to loose some amount of m2 messages. But it cannot afford to loose any of m1 messages.
In normal operation mode, volume of m2 is about twice as m1. But in some situations m1 can be higher and m2 can be low.
The expectation is to serve the m1 traffic no matter what the volume of m2 traffic is.
Priority based mediation can be configured at two levels.
At both configuration levels priority-executor configuration is present.
<priority-executor name="priority-executor"> <queues isFixed="true|false" nextQueue="class implementing NextQueueAlgorithm"> <queue [size="size of the queue"] priority="priority of the messages put in to this queue"/>* </queues> <threads core="core number of threads" max="max number of threads' keep-alive="keep alive time"/> </priority-executor>
An executor is a Thread Pool Executor with separate queues for different priorities.
The queues can have a fixed depths or they can be un-bounded queues. This is controlled by the isFixed attribute.
A executor should have at least two or more queues. If only one queue is used there is no point in using a priority executor. It only adds some overhead.
A Queue can have a size and a priority. If the queues has unlimited length, no more than core threads will be used.
A Priority Executor has a core number of threads. When ESB is started with the priority executor, this number of threads will be created. Max is the maximum number of threads this executor will have. If the number of threads in the executor exceeds the core threads, they will be in active for the keep-alive time only. After the keep-alive time those threads will be be removed from the system.
HTTP level configuration is done by using a separate xml configuration file.
This configuration file should be referred from the Nhttp transport receiver configuration in the axis2.xml.
<parameter name="priorityConfigFile">file path</parameter>
Here is the syntax of the priority configuration at the HTTP level.
<Priority-Configuration> <priority-executor name="priority-executor"> <queues isFixed="true|false"> <queue [size=""] priority=""/>* </queues> <threads core="core number of threads" max="max number of threads' keep-alive="keep alive time"/> </priority-executor> <!-- conditions for calculating the priorities based on HTTP message --> <conditions defaultPriority="default priority as an integer"> <condition priority="priority value as an integer"> one evaluator, this evaluator can contain other evaluators </condition> </conditions> </Priority-Configuration>
Priority executor configuration is explained in the previous section.
A priority configuration can have multiple conditions. A condition is evaluated over a HTTP message. A condition return true or false. If a condition evaluates to true, message will be executed with the priority associated with the condition.
A condition can have a single boolean expression. Here are the supported boolean operators and expressions.
eqaul and match are leaf level expressions. 'not', 'and' and 'or' can contain other expressions.
<equal type="header | param | url" source="" value=""/>
Equal fetch the value specified by the source from a HTTP header, parameter. Then it equals it against the value attribute. For example
<eqaul type="header" source="priority" value="10"/>
This gets the HTTP header named priority and equals it to 10. If the values are equal it return true.
<match type="header | param | url" source="" regex=""/>
Match is similar to equal. Only difference is instead of just trying to see weather the two values are equal, it uses a regular expression to match the source. If the regular expression matches the source it will return true
<not> any boolean operator or boolean expression </not>
Not can have another boolean expression inside of it. Not negates the boolean value returned by the boolean expression inside.
<and> two or more boolean boolean expressions </and>
And can have two or more boolean expressions. It does the boolean and for the enclosing expressions.
<or> any boolean operator or boolean expression </or>
"or" is same as "and" configuration except it gets the boolean 'or' for the enclosing expressions.
At mediation level multiple priority executors can be defined at the top level of the sypase configuration. These executors should have a unique name.
<priority-executor name="priority-executor"> <queues isFixed="true|false"> <queue [size=""] priority=""/>* </queues> <threads core="core number of threads" max="max number of threads' keep-alive="keep alive time"/> </priority-executor>
Executor configuration is same as the one described earlier.
To execute a sequence using a priority-executor enqueue mediator should be used. Here is the syntax of the enqueue mediator.
<enqueue priority="priority as an integer" executor="executor name to submit the responses" sequence="sequence name to be executed with the given priority"/>
Enqueue mediator should be pointing to an priority-executor. Message coming in to the enqueue mediator will be executed using this priority-executor. Also it specifies a priority. This priority is applied to the messages. sequence attribute specifies the sequence to be executed with the given priority.