GLU Functions

GLU Functions and Formulas are available for use in derived parameters as well as request and response handlers.

A single derived parameter or handler can only be used with one FUNCTION i.e. you can’t mix two FUNCTIONS. If for example, you need a Derived Parameter to calculate the difference in the time NOW ( which is a FUNCTION) and another parameter, you can use the DIFFTIMESTAMP but you’ll first need to define a Derived Parameter call say ‘timeNow’ using the NOW FUNCTION and thereafter use the DIFFTIMESTAMP FUNCTION with FUNCTION notation as follows:


It is possible to execute functions only by checking the box Run Function, as some functions do not return values, such as removing data from the cache.

The below screenshot shows the tick box selected and the parameter field not being shown.

All functions are accessible through the Predefined Functions feature.

It is possible to get a list of the predefined functions as a drop-down.

When you select the Predefined Functions tick box, the drop-down will show.

If you choose the Predefined Function then a function with the template of the associated parameters will be overwritten into the Function or Formula box.

If you untick the box the Predefined Function field will disappear. However, the function will remain.

Note: FORMULAs involve the use of mathematical calculations and are always prefixed with the ‘=’ symbol. FUNCTIONs are not preceded by any symbol.


This Derived Parameter is the most basic of FUNCTIONS in that it enables one to create a Derived Parameter that has a specific INITIAL value. IN the example below the starting value will be ‘0’ for the ‘redeemedAmountFormatted’ Derived Parameter. This enables one to add for example a Handler rule that will overwrite this parameter in the event that another received parameter e.g. ‘redeemedAmount’ is NOT NULL.

IFNULL Function


The IFNULL Function is used to check whether a parameter is NULL and if so return another parameter that is specified by the user (similar to a try/catch statement in JavaScript).

If a Derived Parameter is created with the IFNULL Function and the first parameter is NULL, it will return a specified parameter or (if no parameter is specified) a static value. If the first parameter is not NULL then it will return the value of the first parameter.


Example 1:


(Param1 isn't sent at all)

Param2 = "Hello_World"

IFNULL returns "Hello_World"

Example 2:


Param1 = "Big_Bang"
Param2 = "Hello_World"

IFNULL returns "Big_Bang"

Example 3:


(Param1 isn't sent at all) 

Param2 = "Hello_World" 

IFNULL returns "Bye_World"

IFEMPTY Function


The IFEMPTY Function is similar to the IFNULL Function and is used to check whether a parameter is EMPTY (has no assigned value) and if so, return another parameter that is specified by the user.

If a Derived Parameter is created with the IFEMPTY Function and the first parameter is EMPTY, it will return a specified parameter or (if no parameter is specified) a static value. If the first parameter is not EMPTY then it will return the value of the first parameter.


Example 1:


Param1 = ""  

Param2 = "Hello_World"

IFEMPTY returns "Hello_World"

Example 2:


Param1 = "Big_Bang"
Param2 = "Hello_World"

IFEMPTY returns "Big_Bang"

Example 3:


Param1 = ""  

Param2 = "Hello_World" 

IFEMPTY returns "Bye_World"

GLU Auto-Test Reference: Sticky Tests: 1.37               App: Sticky Validation >> Transaction: Formulas & Functions >> Formula: 2. IFEMPTY Formula



The IFNULLOREMPTY Function is a combination of the IFNULL and IFEMPTY Functions and is used to check whether a parameter is either NULL OR EMPTY and if so, return another parameter that is specified by the user.

If a Derived Parameter is created with the IFNULLOREMPTY Function and the first parameter is NULL OR EMPTY, it will return a specified parameter or (if no parameter is specified) a static value. If the first parameter is not NULL OR EMPTY then it will return the value of the first parameter.


Example 1:


Param1 = ""  
Param2 = "Hello_World"

IFNULLOREMPTY returns "Hello_World"

Example 2:


Param1 = "Big_Bang"
Param2 = "Hello_World"

IFNULLOREMPTY returns "Big_Bang"

Example 3:


(Param1 isn't sent at all)  
Param2 = "Bye_World" 
IFNULLOREMPTY returns "Bye_World"

GLU Auto-Test Reference: Sticky Tests: 1.38               App: Sticky Validation >> Transaction: Formulas & Functions >> Formula: 3. IFNULLOREMPTY Function

SPLIT Function


The SPLIT Function allows the user to split a string at a specific character in the string. This function will return an array with the split strings as elements in that array (with the index starting at 0). It will split the string at each occurrence of the specified character.


Example 1:


stringOne = "Jim_and_Pam"

               "value": "Jim",
               "key": "0"
               "value": "and",
               "key": "1"
       {       "value": "Pam",
               "key": "2"

GLU Auto-Test Reference: Sticky Tests: 1.39               App: Sticky Validation >> Transaction: Formulas & Functions >> Formula: 4. SPLIT Function


This FUNCTION is used to pull a string out of an Arra, the function format is as follows:

CREATE_VALUE_AS_STRING_FROM_ARRAYS(<sourceArrayName1>[].<sourceArrayName2>[], <attributeName>, [<delimiterForArray> <delimiterBetweenValues>])

sourceArrayName1 is the name of the top level of the collection path.

sourceArrayName2 is the name of the next level down from the top of the collection path. You can add extra levels to your collection path as needed.

attributeName is the actual attribute you are looking to pull into a string.

delimiters are optional so if not included in the Function, the string won’t have any delimiters. If a delimiter is a comma, … you must wrap it with <> i.e. <,> so that it’s not seen by the FUNCTION as a separator. If the delimiterForArray is a semi-colon and delimiterBetweenValues for example a pipe then the final part of your FUNCTION will look like this: [; |] … note the space in between.


 CREATE_VALUE_AS_STRING_FROM_ARRAYS(boards[].selections[], selection, [; <,>])

The above FUNCTION will take the following Array:

{	"boards": [    {"selections": [ "4","14","18"]},
                              {"selections": ["2","19","20"]},
                              {selections": ["1","12","18"]}                   ]

… and transform it into a string…

 "numbers": "4,14,18 ;2,19,20,35 ;1,12,18 ;11,22,36 " 

So when configuring this Derived Parameter, you would enter ‘numbers’ as the ‘derivedParameterName’ and you’d enter:

CREATE_VALUE_AS_STRING_FROM_ARRAYS(incomingBoards[].selections[], selection, [; <,>])

… in the ‘Formula’ box.

GLU Auto-Test Reference: ( Reference to be updated ) Sticky Tests: 1.40.2               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: CREATE_VALUE_AS_STRING_FROM_ARRAYS



This function adds a value to an array when required


input has only one rctNum: [unmarshalled to SerialNumber in Token[] array]

 <stdToken units="66.666664"
       				tariff="aaaa.aa kWh @ 065.72 c/kWh: kWh @ 075.42 c/kWh: kWh @ 109.50 c/kWh: dddd.dd kWh @ 120.10 c/kWh : "
       				desc="Normal Sale"

<bsstToken bsstDate=”2020-12-09 08:16:00 +0200″

        				tariff="aaaa.aa kWh @ 065.72 c/kWh: kWh @ 075.42 c/kWh: kWh @ 109.50 c/kWh: dddd.dd kWh @ 120.10 c/kWh : "
        				desc="FBE Token"

To pass an array of two tokens, each with a value for SerialNumber:


GLU Auto-Test Reference: ( Reference to be updated ) Sticky Tests: 1.31, 1.34               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: ADD_ATTRIBUTE_TO_ARRAY_WITH_FIX_VALUE

LENGTH Function


This function returns the length of the string.


To get the length of this string “attribute”: “Hello_world” use the function as follows:

1 – Name your derived parameter e.g. lengthOfAttribute
2 – Use the function: ${attribute}.length

The response will be “lengthOfAttribute”: “11” ( 11 is the length of the string Hello_world ).

GLU Auto-Test Reference: ( Reference to be updated ) Sticky Tests: 1.41             App: Sticky Validation >> Transaction: Formulas & Functions >> Formula: LENGTH Function

NOW Function (Current Date with Pattern)

Use the NOW Function in a derived parameter to set the date and time at the time that the variable is defined as the GLU.Engine runs.

NOW() which will store the time with default format for example Fri Aug 14 13:10:22 SAST 2020

NOW which will store the time with the format as for example 14/08/2022

Or if you want to specify the format you can enter for example: NOW(YYYY-MM-DD HH:MM:SS)


See below the example of how the “now” variable is used in a template.

{ “responseMessage”: “variableParameterResponse”, “staticTimestamp”: “${staticTimestamp}”, “now”: “${now}” }

GLU Auto-Test Reference: ( Reference to be updated ) Sticky Tests: 1.42               App: Sticky Validation >> Transaction: Formulas & Functions >> Formula: Formula NOW


dateformat(${date},yyyy-MM-dd HH:mm:ss:ms)

This function is used to change the date format


You have a date in this format “date”:”29/09/2021″ (dd/MM/yyyy) and you want to change it to another format
e.g. “dateInNewFormat”:”2021-09-09 00:00:00:00″ (yyyy-MM-dd HH:mm:ss:ms).

GLU Auto-Test Reference:( Reference to be updated ) Sticky Tests: 1.44               App: Sticky Validation >> Transaction: Formulas & Functions >> Formula: DATE FORMAT Function

RANDOM Function


This function returns a random number between two numbers as specified in the example.



The response can be any random number between 10 and 20  
e.g. for the first request response is 17, for the second request response is 11 ....etc.

GLU Auto-Test Reference: ( Reference to be updated ) Sticky Tests: 1.45               App: Sticky Validation >> Transaction: Formulas & Functions >> Formula: RANDOM Function



This will take a parameter and pad the right of the string with specified values up to x number of characters.

padrightstring(${parameter},<x is the total number of characters>,<y is the character to pad with>)


For example padrightstring(${string},8,0)               
"string" is : 555
Pad with 0
Total number of characters 8 The response will be 55500000

GLU Auto-Test Reference:( Reference to be updated ) Sticky Tests: 1.48               App: Sticky Validation >> Transaction: Formulas & Functions >> Formula: PADRIGHTSTRING Function



This will take a parameter and pad the left of the string with specified values up to x number of characters.

padleftstring(${parameter},<x is the total number of characters>,<y id the character to pad with>)


For example padleftstring(${string},8,0)               
"string" is : 555
Padleft with 0
Total number of characters 8 The response will be 00000555

GLU Auto-Test Reference: Sticky Tests: 1.49               App: Sticky Validation >> Transaction: Formulas & Functions >> Formula: Formula PadleftString


stripstart(${parameterName}, stripChar)

You can use the STRIPSTART FUNCTION to remove all leading characters that match the STRIPSTART stripChar


STRIPSTART(${accountNumber}, 0)

This will remove all ‘0’ characters from the left side of the accountNumber parameter e.g. 00000867512837656 will be saved as 867512837656 and 00087693487672938 will be saved as 87693487672938

GLU Auto-Test Reference: 1.53               App: Sticky Validation >> Transaction: Formulas & Functions >> Formula: Function STRIPSTART



This function calculates the difference between two date in milliseconds. e.g difftimestamp(${dateTwo},${dateOne}):


difftimestamp = 31536000000 ( one year calculated in milliseconds ) = 1*356*24*60*60*1000

Example Lets say you need to calculate a time in minutes between the current time and an expiry time. To do this you will need to use a combination of FUNCTIONS and FORUMULAS as follows:

First, create a Derived Parameter called ‘timeNow’ using the ${NOW} function

Then create a Derived Parameter called ‘calcedExpiryTimeMilliSeconds’ using the DIFFTIMESTAMP FUNCTION. Note that this difference is calculated in milliseconds hence naming it to be clear.

Now you can use a FORMULA to convert ‘calcedExpiryTimeMilliSeconds’ to ‘minutes’ as follows:

GLU Auto-Test Reference: Sticky Tests: 1.47               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: DIFFTIMESTAMP



This will take the right x number of characters from a parameter. ${parameter}.rightString[<number of characters>]


example of use ${tax_id}.rightString[8]

GLU Auto-Test Reference: Sticky Tests: 1.50               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: RIGHTSTRING


SUBSTRING(${string}, startNumber, endNumber)

Substring function extracts a string with a specified length, starting from/ending at a given location in an input string. The purpose of Substring is to return a specific portion of the string.

This function can also be used with variable lengths that can be sent in the request.


"stringOne" is : Hello_world 

Derived parameter :  SUBSTRING(${stringOne},5)

Response will be : "Hello" ( it extracts 5 first characters, as specified in the example [0.5] )

GLU Auto-Test Reference: Sticky Tests: 1.51.2               App: Sticky Validation >> Transaction: Formulas & Functions >> Formula: SUBSTRING Function



Substring Between function also extracts a string in a specified position in the string, starting from/ending at a given text in an input string.


"stringOne" is : DECOLORIZE 
Derived parameter : SUBSTRING_BETWEEN(${stringOne},DE,IZE)
Response will be : "COLOR" ( it extracts the text between the two defined texts 1 & 2, as specified in the example (DE & IZE) )

GLU Auto-Test Reference: Sticky Tests: 1.51.3               App: Sticky Validation >> Transaction: Formulas & Functions >> Formula: SUBSTRING BETWEEN Function



This function returns the current timestamp calculated in milliseconds.


Current date & time now is : Tuesday 9 March 2021 08:50:38.955 
Timestamp value will be 1615279838955

GLU Auto-Test Reference: Sticky Tests: 1.46               App: Sticky Validation >> Transaction: Formulas & Functions >> Formula: TIMESTAMP Function

UTC Time Function


This function returns the current date time in UTC time. The format returned: 2022-06-22T13:52:50.083Z

Concatenate Function

${String1}:${string2}:${string3}: ……

This function is used to join two strings or more together.



Response will be 09/03/2021:Hello_world:Tuesday

GLU Auto-Test Reference: Sticky Tests: 1.52               App: Sticky Validation >> Transaction: Formulas & Functions >> Formula: Concatenate Function



This function returns the name of the server where the GLU application is running.


For example my application is running on localhost.

the response will be: “DESKTOP-JH9PA6A”

GLU Auto-Test Reference: Sticky Tests: 1.56               App: Sticky Validation >> Transaction: Formulas & Functions >> Formula: GLU SERVER NAME



This function returns the transaction ID. The transaction id is a unique value for the transactions. Each new transaction will have a new transaction id.


For example, the ID of the test transaction is “b67f0087-a3c4-4e28-b8f1-d01b21086b1d”

GLU Auto-Test Reference: Sticky Tests: 1.57               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: GLU TRX ID



GLU Redelivery counter is used within the retry function.

This is the counter for the number of retries that have been sent. See the timeout/retry function for more details.

GLU Auto-Test Reference: Sticky Tests: 1.58               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: GLU Redelivery Counter


ADD_DAYS_TO_DATE(${date},<numbers of days to add>)

This function is used to add days to date. The number of days can be sent in the request (as variable) e.g. ADD_DAYS_TO_DATE(${date},${numberOfDays})



The “date” is 09/03/2021

The number of days to add is 2

The response will be 11/03/2021

GLU Auto-Test Reference: Sticky Tests: 1.59, 1.60               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: ADD DAYS TO DATE Function


REMOVE_DAYS_TO_DATE(${dateOne}, <number_of_days_to_remove>)

This function is used to remove days from date.



The “date” is 09/03/2021

The number of days to remove is 2

The response will be 07/03/2021

GLU Auto-Test Reference: Sticky Tests: 1.61               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: REMOVE DAYS TO DATE Function



The DIFFERENCE_BETWEEN_DATES Function calculates the difference between two dates, the format is as follows e.g. DIFFERENCE_BETWEEN_DATES(${dateOne},${dateTwo})

The format of the two Dates does not matter.

The result is a count in DAYS. Note if you want to calculate a time difference use the DIFFTIMESTAMP Function.

GLU Auto-Test Reference: Sticky Tests: 1.62               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: Function DIFFERENCE_BETWEEN_DATES



NewCacheValuepid the variable value will be placed in the cache

cachepid is the name the parameter will hold within the cache


The example below shows how the SET_DATA_TO_CACHE is used in a handler to assign value to the cache value cachepid.

GLU Auto-Test Reference: ( Reference to be updated ) Sticky Tests: 1.93               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: DIFFERENCE_BETWEEN_DATES


To access a cached value GET_DATA_FROM_CACHE function can be used.

The GET_DATA_FROM_CACHE function has multiple forms.

GET_DATA_FROM_CACHE(chicken[], message, track, ${findme})

Both are explained with the examples below.

EXAMPLE : GET_DATA_FROM_CACHE(array[], parm1, parm2, ${variable})

GET_DATA_FROM_CACHE(chicken[], message, track, ${findme})


chicken[] is an array containing a list of data which needs to be looked up and a value retrieved from.

like this table below


message when an exact match has been found, this is the value in the column which will be returned.

track is the column in the array where the findme value will be searched for and an exact match identified.

$(findme) is a variable to be found in the array in the column specified ( track )

if there is not a match, then it will return a NULL value.

This can only be used with Arrays.

The array needs to be populated in a separate transaction using the ‘store in cache’ function.

This command can only be used in a Derived Parameter



When there is a single parameter in a cache, it can be retrieved and placed in a derived parameter with the GET_DATA_FROM_CACHE command. See the example below

GLU Auto-Test Reference: Sticky Tests: 1.63,               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: GET DATA FROM CACHE



To do a comparison from a cached value in the engine against a parameter, use the following in a Derived Parameter or a Handler: GET_MAPPED_FROM_CACHE_CONTAINS

This command will return a look up value for a value in the cached table which is contained in the parameter to compare against. It does this by iterating through the look up values in the array to see if the correct sequence of characters exists in the parameter.


Parameter: valueToLookInto:”What is my fruit?”

Array of data stored in the cache.


Function specified as:


GLU Auto-Test Reference: Sticky Tests: 1.66               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: GET DATA FROM CACHE CONTAINS


GET_MAPPED_ARRAY_FROM_CACHE(arrayToCache[], saveAttributeArrayInCache2,saveAttributeArrayInCache1,${conditionCache2},-);

This function is used to get a mapped array in cache with variable condition. arrayToCache[] is the name of the array where the parameters saveAttributeArrayInCache2 and saveAttributeArrayInCache1 are saved in cache. conditionCache2 is the position of the parameter in the array.


Save the parameter saveAttributeArrayInCache1 in the array arrayToCache[] in cache
Save the parameter saveAttributeArrayInCache2 in the array arrayToCache[] in cache

Now you have the following array saved in cache

"arrayToCache":[{"saveAttributeArrayInCache1": "value 1"},{"saveAttributeArrayInCache2": "value 2"}]

You can use the function to get one of two parameters using the condition=1 or condition=2
The response will be:

"arrayToCache": [{"saveAttributeArrayInCache1": "value 1"}]


"arrayToCache": [{"saveAttributeArrayInCache2": "value 2"}]

GLU Auto-Test Reference: ( Reference to be updated ) Sticky Tests: 1.65               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: GET MAPPED ARRAY FROM CACHE



Use this FUNCTION to create an array.

The format is as follows:



For a Derived Parameter called 'scoreArray' ... the formula: CREATE_ARRAY(${countScore},[Sore],[true]) where the value of 'countScore' = 5 ... would  result in and array that looks like this:                       
] i.e. with 5 attributes ... note that this means that the arraySizeParameter must be an integer.

GLU Auto-Test Reference: Sticky Tests: 1.68               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: CREATE_ARRAY


CREATE_ARRAYS_FROM_STRING_WITH_ATTRIBUTES(${stringValue},[arrayName arraychildName….], [attribute], [delimeter1 delimeter2…],[extraAttribute1 extraAttribute2…],[extraAttributeValue1 extraAttributeValue2…], arrayIndex)

stringValue is the name of the source string parameter that you have already unmarshalled into the GLU.Engine.

arrayName arraychildName…. denotes the Array tree structure which can be ‘n’ levels deep.

attribute is the name of the parameter you’ll be saving into your lowest level array from the source stringValue.

delimeter1 delimeter2… denotes the delimiters in the stringValue that indicate the breaks in the tree structure … there must be the same number of delimeters as there are arrayNames.If a delimiter is a comma , … you must wrap it with <> i.e. <,> so that it’s not seen by the FUNCTION as a separator. If the delimiterForArray is a semi-colon and delimiterBetweenValues for example a pipe then the final part of you FUNCTION will look like this: [; |] … note the space in between.

extraAttributeName1 extraAttributeName2… and theextraAttributeValue1 extraAttributeValue2… are matching “Attribute” : “Value” pairs that can be added to the Array. If you are using a ‘map’ instead of a key-value paired ‘array’ you don’t need to define the ‘extraAttributeNames’.

arrayIndex denotes the starting position in the array being created for the extraAttributes. If this is ‘0’ the theextraAttributeValue1 and if paired with an extraAttributeName will be at the first tier of your array tree, if this is ‘1’ it will appear at the second tier, and so on.

Example 01 – arrayIndex=0, extraAttributeName=defined

CREATE_ARRAYS_FROM_STRING_WITH_ATTRIBUTES(${numbers},[boards selections], [], [; <,>],[quickpick],[false], 0)
This takes this: 
"numbers": "1,2,3,4,5,6;11,12,13,14,15,16"
and transforms it into this array: 
"boards" : [{"quickpick": "false","selections" : ["1","2","3","4","5","6"]},{"quickpick": "false","selections" : ["11","12","13","14","15","16"]}]

Example 02 – arrayIndex=1, extraAttributeName=null

CREATE_ARRAYS_FROM_STRING_WITH_ATTRIBUTES(${numbers},[boards selections], [], [;<, >],[],[00], 1)  
This takes this: 
"numbers": "1,2,3,4,5,6;11,12,13,14,15,16"
and transforms it into this array: 
"boards" : [{"selections" : ["00","1","2","3","4","5","6"]},{"selections" : ["00","11","12","13","14","15","16"]}]

GLU Auto-Test Reference: Sticky Tests: 1.70               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: CREATE_ARRAYS_FROM_STRING_WITH_ATTRIBUTES


This function is used to replace values within strings… the function format is as follows:

"string" is the string you want to modify.
"valueToReplace" is the value you want to replace in the string.
"valueToReplaceWith" is the value you want to replace within the string.

Example 01

The Replace function transforms the string to: “string”:”Hello_user”

Sticky Tests: 1.73               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: Replace



This FUNCTION is used to encode a string to either Base32 or Base64.

Base32 is the base-32 numeral system. It uses a set of 32 digits, each of which can be represented by 5 bits (25). One way to represent Base32 numbers in a human-readable way is by using a standard 32-character set, such as the twenty-six upper-case letters A–Z and the digits 2–7.

Common to all binary-to-text encoding schemes, Base64 is designed to carry data stored in binary formats across channels that only reliably support text content. A typical use is to encode binary data (such as an image); the resulting Base64 data will only contain 64 different ASCII characters, all of which can reliably be transferred across systems that may corrupt the raw source bytes.

ENCODESTRING32 encodes string to Base32
Function: ENCODESTRING32(${string})    
ENCODESTRING64 encodes string to Base 64
Function: ENCODESTRING64(${string})  

GLU Auto-Test Reference: 1.54, 1.55               App: Sticky Validation 18, 19 >> Transaction: Formulas & Functions >> Function: ENCODESTRING



This FUNCTION is used to decode a string from either Base32 or Base64 to ASCII.

Base32 is the base-32 numeral system. It uses a set of 32 digits, each of which can be represented by 5 bits (25). One way to represent Base32 numbers in a human-readable way is by using a standard 32-character set, such as the twenty-six upper-case letters A–Z and the digits 2–7.

Common to all binary-to-text encoding schemes, Base64 is designed to carry data stored in binary formats across channels that only reliably support text content. A typical use is to encode binary data (such as an image); the resulting Base64 data will only contain 64 different ASCII characters, all of which can reliably be transferred across systems that may corrupt the raw source bytes.

DECODESTRING32 decodes Base32 to string
Function: DECODESTRING32(${string})    
DECODESTRING64 decodes Base64 to string 
Function: DECODESTRING64(${string})

GLU Auto-Test Reference: 1.103               App: Sticky Validation 18, 19 >> Transaction: Formulas & Functions >> Function: DECODESTRING



When you need to create a datetime value which is a set time PERIOD different (ahead or behind) another datetime use this FUNCTION. It may be that a transaction should have a 5 min time to live in which case you can use ADD_PERIOD Function to add 5 mins.

The FUNCTION Structure options available are as follows: ADD_PERIOD(${param},${daystoAdd},periodType)


Period Type List – second – minute – hour – day – week – month – year

Some examples:

1- add to date
ADD_PERIOD(${currentDate}, 60, second) 
ADD_PERIOD(${currentDate}, 1, day)
REMOVE_PERIOD(${currentDate}, 2, week)
2- remove from date
REMOVE_PERIOD(${currentDate}, 60, second)
REMOVE_PERIOD(${currentDate}, 1, day)
REMOVE_PERIOD(${currentDate}, 2, week)

So some practical examples of result dates which you may need to manipulate:

add 60 second currentDate: Wed Sep 23 11:12:49 GST 2020 newDate:Wed Sep 23 11:13:49 GST 2020
add 5 minute currentDate: Wed Sep 23 11:12:49 GST 2020 newDate:Wed Sep 23 11:17:49 GST 2020
add 2 hour currentDate: Wed Sep 23 11:12:49 GST 2020 newDate:Wed Sep 23 13:12:49 GST 2020
add 3 day currentDate: Wed Sep 23 11:12:49 GST 2020 newDate:Sat Sep 26 11:12:49 GST 2020
add 6 year currentDate: Wed Sep 23 11:12:49 GST 2020 newDate:Wed Sep 23 11:12:49 GST 2026
add 2 week currentDate: Wed Sep 23 11:12:49 GST 2020 newDate:Wed Oct 07 11:12:49 GST 2020
remove 60 second currentDate: Wed Sep 23 11:12:49 GST 2020 newDate:Wed Sep 23 11:11:49 GST 2020
remove 5 minute currentDate: Wed Sep 23 11:12:49 GST 2020 newDate:Wed Sep 23 11:07:49 GST 2020
remove 2 hour currentDate: Wed Sep 23 11:12:49 GST 2020 newDate:Wed Sep 23 09:12:49 GST 2020
remove 3 day currentDate: Wed Sep 23 11:12:49 GST 2020 newDate:Sun Sep 20 11:12:49 GST 2020
remove 6 year currentDate: Wed Sep 23 11:12:49 GST 2020 newDate:Tue Sep 23 11:12:49 GST 2014
remove 2 week currentDate: Wed Sep 23 11:12:49 GST 2020 newDate:Wed Sep 09 11:12:49 GST 2020

GLU Auto-Test Reference: From1.77 to 1.88               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: ADD_PERIOD / REMOVE_PERIOD



decryptedValue is the value to be encrypted

modulus and exponent can be retrieved in the public certificate (provided by the client)

UTF-8 the chartset used to encrypt.

GLU Auto-Test Reference: 1.89               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: ENCRYPT USING RSA PUBLIC KEY



This function converts a date to timestamp.


The "date" is : "17/03/2020"
The response will be : 1584396000000

GLU Auto-Test Reference: 1.91               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: Covert Date to Timestamp


This function takes two ‘columns’ in an array and merges them.

MERGE_VALUES_IN_ARRAY(product,[type charge],typecharge,-)

The function setup is as follows: MERGE_VALUES_IN_ARRAY(product,[type charge],typecharge,-)

Position 1: e.g. product – this is the name of the array that already exists
Position 2: e.g. [type charge] – these are the two ‘columns’ in the array that we want to merge
Position 3: e.g. typecharge – this is the new column name
Position 4: e.g. – This is the delimiter that we want to set between the two values in the columns.

So if the array has a type = voucher and charge = 1000, the result will be a new column with voucher-1000

If you need to do a lookup in the array and match on two values, this can assist in creating the combined lookup key.

GLU Auto-Test Reference: 1.95               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: MERGE_VALUES_IN_ARRAY

HMAC SHA 1 Encoder


Description: HMAC(Hash-based message authentication code) is a message authentication code that uses a cryptographic hash function such as SHA-1 and a secret key known as a cryptographic key. HMAC is more secure than any other authentication codes as it contains Hashing as well as MAC params (String message, String SecretKey) This function returns a base 64 encoded string.

GLU Auto-Test Reference: 1.98.B               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: HMAC_SHA_1_BASE64_ENCODER

HMAC SHA 256 Encoder


Description: HMAC(Hash-based message authentication code) is a message authentication code that uses a cryptographic hash function such as SHA-256 and a secret key known as a cryptographic key. HMAC is more secure than any other authentication codes as it contains Hashing as well as MAC params (String message, String SecretKey) This function returns a base 64 encoded string.

GLU Auto-Test Reference: 1.98.A               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: HMAC_SHA_256_BASE64_ENCODER

AES 256 Encryption (CBC)


Description: Advanced Encryption Standard(AES) is a symmetric encryption algorithm. AES is the industry standard. it generates AES encrypted password. It provides CBC mode of encryption. Function parameters: (String message, String SecretKey, String initializationVector optional) Function Returns : base 64 encoded string

GLU Auto-Test Reference: 1.97               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: ENCRYPTION_AES_256_BIT_MODE_CBC_BASE64_ENCODER

AES 256 Decryption (CBC)


Description: The decryption process is similar to the encryption process but in reverse order return: base 64 decoded string

GLU Auto-Test Reference: 1.100               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: DECRYPTION_AES_256_BIT_MODE_CBC_BASE64_DECODER


BASE64_TO_HEX(${HMAC}) Converts the base64 value to Hex.

GLU Auto-Test Reference: 1.99               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: BASE64_TO_HEX



This function creates a MD5 hexadecimal hash value of the parameter passed in.

GLU Auto-Test Reference: 1.112               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: MD5_HEX



GLU Auto-Test Reference: 1.101               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: URL_ENCODER



GLU Auto-Test Reference: –               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: Consolidate



Converts the contents of a parameter to lowercase.

GLU Auto-Test Reference: 1.1.07               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: Lower Case


Converts the contents of a parameter to uppercase.


GLU Auto-Test Reference: 1.1.08               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: Upper Case


= ${msisdnlast2Digit}.% 2

The mod command returns the remainder for a division.

i.e. 5 mod 17 will return 2

as when you divide 5 by 17 it goes in 3 times with 2 left over (remainder)

in the example below where msisdnlast2Digit is to be divided by 2

the mod command is %

the routekey can only be 0 or 1, depending on the value of msisdnlast2Digit

GLU Auto-Test Reference: 1.34               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: MOD


The IETF/W3C XML Signature standard (usually referred to as XML-DSig) is a general framework for digitally signing documents; XAdES specifies precise profiles of XML-DSig that provide certain guarantees. XAdES-BES (for “Basic Electronic Signature”) provides basic authentication and integrity protection, which are essential for advanced electronic signatures in payment systems


messageISO20022 is the message to sign.

certificate is the Public Certificate to sign message with.

privateKey is the Private Key to sign message with.



SignedMessage is the message to verify, including XML Signature.

certificate is the Public Certificate or Public Key.

false to indicate if Public Key is used or not. IE if you were to reference the Public Key, your formula should look like this:


JSON Web Signature (JWS) or JSON Web Encryption (JWE)

JWS requires some derived parameter inputs to create a signed Jose payload. JWS consists of three parts: Header, Payload, and Signature. Each of these parts is encoded in BASE64URL, then all three parts are connected in one line, the delimiter is a dot.

Header requires an x5t header parameter: Base64url-encoded SHA-1 thumbprint (a.k.a. digest) of the DER encoding of the X.509 certificate.



The generates the SHA-1 Thumbprint of a Certificate: GENERATE_FINGERPRINT(${certWithTags},SHA-1) [saved as x5tSHA in this example]



This Base64URL encodes the Thumbprint: ENCODE_HEX_TO_BASE64(${x5tSHA})

[saved as x5t in this example, and referenced in a further derived parameter: headerJWS: {“alg”: “RS256″,”typ”: “JOSE”,”x5t”: “${x5t}“}]

GLU Auto-Test Reference: 1.109               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: Encode HEX to BASE64



This combines the previously created values to create the signed JWS payload: GENERATE_JWS(${headerJWS},${responseBodyStart},${rpkPrivateKey},${algorithmJWS})

GLU Auto-Test Reference: 1.102               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: GENERATE_JWS


CURRENT_NANO_TIME is a function that returns the current time in nanoseconds. This function provides a highly precise measurement of time, allowing for very accurate timing and performance measurements. The value returned by this function is often used in high-performance computing applications, where timing accuracy is critical. By using nanosecond precision, this function provides a level of accuracy that is not possible with other types of timing functions.


The current nano time now is 17122459102375

GLU Auto-Test Reference: 1.104              App: Sticky Validation >> Transaction: Formulas & Functions >> Function: CURRENT_NANO_TIME



This function returns the entire response body. e.g. you want to use the body in another transaction, so you can save it as a derived parameter and use it where needed.

GLU Auto-Test Reference: 1.111               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: GET_BODY



This function returns the parameter value from a specified path in a JSON payload. GET_VALUE_FROM_JSON_PAYLOAD(${jsonPayload2},array[1].param)

GLU Auto-Test Reference: 1.110               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: GET_VALUE_FROM_JSON_PAYLOAD



This function helps to unmarshal from an array.

In the example below if you wanted to un-marshal a value within index 1 of the array ‘chickenTypes’

    "chickenTypes": [
                   "type": "Silkie",                 
                    "type": "Broiler", 

You could use this command.


“chickenTypes” is the name of the array

“type” is the attribute

“1” is the index of the attribute

Which would result in a value of “Silkie”



Where “balances” is the parent array: brings all children values into root array.

Example: balances[].balanceResources[] – parameters inside balanceResources[] will now print inside balances[]

GLU Auto-Test Reference: 1.69               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: CREATE_ARRAY_FROM_ARRAY_AND_ARRAY_CHILDREN

AES GCM Decryption


The parts of this are:

Payload (the encrypted payload that comes in)

DecrKey – your key you’ve been given

InitVector – that parameter that comes in from the header on the incoming request.

SecretKeySpecAlgorithm – This must be = AES

cipherTransformation – This must be = AES/GCM/NoPadding

authTag – this must be the authTag in comes in from the header on the incoming request.

GLU Auto-Test Reference: 1.113               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: DECRYPT_SEC_KEY_CIPHER



The following function applies the Luhn algorithm rules. The output is either: ‘false'(doesn’t pass Luhn test) or ‘true'(does pass Luhn test),


GLU Auto-Test Reference: 1.115               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: VALIDATE_CARDS_WITH_LUHN_ALGO


GENERATE_GUID (short for “Globally Unique Identifier”) is a function or method that generates a unique identifier for an object or entity in a computer system. A GUID is a 128-bit value, typically represented as a string of hexadecimal digits separated by hyphens, that is generated using an algorithm designed to ensure that each GUID is statistically unique.

GUIDs are commonly used in software development and database management, where it is important to have a reliable way of identifying objects or records. Because the chance of two randomly generated GUIDs being identical is extremely low, GUIDs are often used to uniquely identify objects across different systems or networks.

GLU Auto-Test Reference: 1.115               App: Sticky Validation >> Transaction: Formulas & Functions >> Function: GENERATE_GUID

Customer Specific Functions



This is an encryption algorithm which is specific for use with a particular PAN type. If you are interested in using this please consult with GLU Support who will explain how and when to use this.


The result will be the pan encrypted.

It takes this “pan”: “1944219200122247”
Returns this “pan”: “1944882297307746”

GLU Auto-Test Reference: 1.90 >> App: Sticky Validation >> Transaction: Formulas & Functions >> Function: TENACITY PAN ENCRYPT

No-Code Myths – Debunked!

Debunking the No-code Myths

The importance of leveraging software to stay competitive in the market and notably the benefits of no-code platforms are important to understand. There are however a number of mis-perceptions and concerns (myths) about no-code platforms, some of the most common of which are outlined below. It is important to recognise these concerns and to understand why they are mis-placed so as to ensure that the opportunities presented by no-code solutions can be embraced.


No-code platforms can lower the cost of building apps and enable experimentation and the exploration of new ideas by building apps and their underlying ‘plumbing’ to test viability and business value quickly. No-code platforms can be used to deliver business mission-critical solutions in isolation, or in some cases, Software developers may still be involved (see Myth #4) to handle more sophisticated requirements. Importantly though, in recent years no-code platforms (such as GLU.Ware) are being used to bring complex Enterprise level Use Cases to life without any software developers being involved.


The concept of using visual tools for software development, known as visual CASE (computer aided software engineering) tools, has been around since the 1970s, but early attempts were complex and required specialised knowledge. As a result, business users turned to homegrown tools like spreadsheets or databases, which were easier to build but had performance and security issues. It wasn’t until the mid-2000s, with advancements in cloud computing and software platforms, that the idea of no-code development began to address the historical challenges of software engineering in a way that is enterprise-ready. While the concept of no-code has been around for decades, its simplicity, ease of use, and ability to address enterprise needs has become widely recognised in recent years.


Low-code and no-code are not the same thing. They both use visual abstractions to simplify software development, but they are designed for different users and offer different benefits. Low-code platforms aim to reduce the amount of code that needs to be written by more junior developers, but still require knowledge of proper application design and architecture, as well as some lightweight coding knowledge. No-code platforms such as GLU.Ware, on the other hand, are intended for non-developers and aim to fully remove the need for coding.


No-code built solutions – both Business Apps and the underlying integration architecture (such as where GLU.Ware is used) can be used for a wide range of software solutions, including mission-critical ones. It is also possible to incorporate traditional software development elements into no-code projects by forming teams that include both no-code creators and software developers. These teams can collaborate efficiently and deliver enterprise-grade applications using no-code.


The idea that no-code development will replace software developers is false. There will always be a need for software developers to work with no-code teams, as software development languages and frameworks continue to evolve and push the boundaries of innovation. No-code tools are typically built on standardised components that were first developed and tested by software developers before being offered as pre-built components for no-code development. Therefore, software developers will continue to play an important role in the development of new digital apps and services.


The notion that no-code platforms are inherently insecure and unreliable is not true. While it is understandable for IT to worry about non-compliant and unreliable apps, modern no-code platforms offer governance and reporting capabilities to ensure proper use. In GLU.Ware, maker-checker controls, workflows and audit trails are just some of the capabilities available to ensure users follow appropriate software ‘development’ (i.e. configuration) practices. By implementing controls and governance, no-code platforms encourage the use of a standard platform that can be consistently governed.


The development practices for no-code platforms should be tailored to take advantage of their unique strengths, rather than simply treating them like traditional development methods. No-code platforms intentionally abstract many details, which means that a different set of skills and backgrounds will be needed for a no-code team. GLU’s no-code methodology is principled on the ability to empower non-developers with the means of creating APIs and Integration components at speed (see the GLU ‘V-model of testing’), which in turn underpins an ability to Innovate at Speed.

Content is based on GLU’s Team experience and interpretation of the summary in Chapter 2 of The No-Code-Playbook – Published 2022 – ISBN 979-8-218-06204-0

Performance Benchmark


GLU.Ware is all about speed. Not just the ability to ‘Integrate at Speed’ but equally so, to ‘Process at Speed’. It’s our mission to ensure that GLU.Engines in a Clients ecosystem are able to scale horizontally and vertically so as to guarantee that those GLU.Engines never cause transactional bottlenecks.

Performance Testing GLU.Engines is thus an integral part of the GLU.Ware Product Quality Assurance discipline. The objective of our performance testing process is to identify opportunities to optimise the GLU.Ware code, its configuration and how it is deployed and in-so-doing to continuously improve the performance of GLU.Engines.

Our Performance Testing process provides GLU and our Clients with insight into the speed, stability, and scalability of GLU.Engines under different conditions.

Test Scenarios

We have defined three performance test scenarios to cover the spectrum of solutions which GLU.Engines can provide integrations for. To focus on maximum throughput we have defined a simple ‘Straight Line Scenario’; to explore the impact of latency on a GLU.Engine we have included the ‘Latency Scenario’; and to understand the impact of complexity we have included the ‘Complex Integration Scenario’.

The Straight Line Scenario is a simple Asynchronous JSON payload pass through, a delivered JSON Payload simply being offloaded downstream to a Rabbit Message Queue.

The ‘Latency Scenario’ is  similar to the Straight line scenario except the payload is a USSD menu payload and it passed through a GLU.Engine which produces transactions in a Rabbit Message Queue.  Those transactions are in turn consumed by another GLU.Engine from a Rabbit Message Queue and they are then passed to a stub which has been configured with variable latency in its response (to emulate latency in downstream Endpoint systems).

The Complex Integration Scenario involves multiple layers of orchestration logic, multiple downstream Endpoints including multiple protocol transformations and multiple synchronous and asynchronous calls to Databases and Message Queues.

Executive Summary of Performance Test Results

Straight Line Integration ScenarioComplex Integration Scenario
SetupContainers: 1 Docker Swarm Manager (4vCPU, 16 GiB) and x2 Worker Nodes (2 vCPU, 4 GiB)VM (4 vCPU, 8 GiB Memory)

Additionally, we have defined a Performance Test scenario for the GLU.USSD solution which is pre-integrated with the GLU.Engine.

USSD SolutionUSSD with Latency Injection
TPS9151 Silo – 350  (Latency of 100ms)
3 Silos – 702 (Latency of 100ms)
SetupContainers: 1 Docker Swarm Manager (8vCPU, 16 GiB) and x2 Worker Nodes (4 vCPU, 16 GiB)VM (2 vCPU, 8 GiB Memory) – GLU.Engine Producer   Containers: 1 Docker Swarm Manager (8vCPU, 16 GiB) and x2 Worker Nodes (4 vCPU, 16 GiB) – RabbitMQ   VM (4 vCPU, 16 GiB Memory) – GLU.Engine Consumer & USSD

GLU.Engines are CPU bound, so ‘vertically scaling’ CPU leads to a better than linear performance improvement. GLU.Engines can also be horizontally scaled behind a load balancer or a Docker Swarm Manger (proxy) if containerised.

GLU.Engines have the ability to absorb latency in End Points up to 100ms and still achieve considerable TPS, with increased TPS being possible if horizontal scaling is architected into the deployment architecture.

Performance Optimization Recommendations

For optimal performance of a system of GLU.Engines, as reflected in the TPS benchmark figures for the systems defined in this document, the following recommendations are advised:

  • Performance of a system is dependent on the performance of each component within the system. A GLU.Engine is only one such component and as such it is important to ensure (monitoring and tracking) for all components connected to the GLU.Engine to ensure they are performing in line with expectations. It is essential to pro-actively monitor the ecosystem and the GLU.Engines specifically with alerts set for all metrics of interest including but not limited to CPU, Memory, Heap Size, Garbage Collection, Disk Space, Latency etc.

  • The deployment architecture of GLU.Engines within the ecosystem has a direct bearing on their performance. Ideally there should be maintained a performance forecast ensuring required additional capacity is planned and implemented in a timely manner. GLU support is available to assist to guide on the required sizing of the deployment architecture. Forecasts should include transaction types, flows, TPS and payload sizes as these all have a bearing on performance.

  • It is recommended to consult GLU support on specifications for GLU.Engines and the servers / VM’s / Containers / networks to help understand any constraints which may exist with the system architectures.

  • It is recommended during ‘normal’ operations log levels for the GLU.Engines should be set to INFO or above (i.e. not DEBUG or TRACE) as Log levels affect GLU.Engine performance. In the event of any suspected problem and during the analysis of the problem log levels can be set to DEBUG to help trace the problem.

  • Where there is a suspected performance degradation of a GLU.Engine the GLU Support team is able to help, however it is essential detailed logs and monitoring metrics are provided along with a full description of the problem scenario to help the support team understand the problem and if need be recreate in the GLU labs. GLU may ask for access to monitoring tools in the client’s environment to collaborate to pragmatically address the problem as quickly as possible.

  • It is essential to ensure the GLU.Engines and associated hardware/ are kept up to date. GLU is always improving the GLU.Ware product and will release performance improvements for time to time.

  • It is recommended to tune and review the performance of other ecosystem components which include load-balancers, docker container managers, databases, message queues, internal applications, as well as internal and external networks and third party applications.

Performance Test Details

Straight Line Scenario Setup

Performance Testing was executed in GLU’s AWS Test Lab within a single VPC.  This ensures little to no degradation in performance due to network communications. Swarmpit was used to manage the Docker environments which were used to run the GLU.Engines and Rabbit MQ processes, 3 Nodes were set up over 3 EC2 instances.

Virtual Machine Sizes

EC2Virtual AWS SystemCPUMemory
Swarm Managert3a.xlarge4 vCPU16 GiB
Swarm Node 1t3.medium2 vCPU4 GiB
Swarm Node 2t3.medium2 vCPU4 GiB

System Versions


JMeter Test Setup Properties

Deployment Architecture

Straight Through Scenario Performance Test Results

Test CriteriaResult
Duration1 hour
% Errors1.22 %
Total Transactions15,846,714

JMeter Results Summary

Rabbit MQ Result Summary


An initial test involving a single node with 4 vCPUs and 16 GiB of Memory achieved a result of 1885 TPS.  The 4400 TPS result was achieved as described above with a Swampit Manager and two nodes, collectively utilising 8 vCPUs and 16 GiB of Memory. This proves that the GLU.Engine is CPU bound such that by reconfiguring and allocating additional CPU on is able to (better than linearly) scale the performance of a GLU.Engine setup.

Complex Scenario Setup

The complex scenario represents 2 benchmarks: the 1st excludes USSD and the 2nd includes USSD.

1st complex test excluding USSD

Performance Testing was executed in GLU’s AWS Test Lab with in a single VPC.  This ensures little to no degradation in performance due to network communication. In this test a docker container was not used, rather a GLU.Engine was deployed directly to a single AWS c5.xlarge (4 vCPU, 8 GiB Memory) EC2 instance. This did not include load-balancing as the objective was to understand the load a single GLU.Engine could achieve.

The diagram below outlines the complex architecture. Note how Jmeter injects transactions and each transaction is orchestrated across a DB connection to msSQL, REST, SOAP and Rabbit connections, returning a response back to Jmeter where the time of the finished transaction was taken.

1st test complex Scenario performance test results

Test CriteriaResult

The graph below illustrates how performance scaled in proportion to VM sizes being increased, with each EC2 instance.


The key factor influencing Performance when minimal latency on the response end points was found to be the number of vCPUs available.

2nd test complex test including USSD

Performance Testing was executed in GLU’s AWS Test Lab within a single VPC. This ensures little to no degradation in performance due to network communications.  Swarmpit was used to manage the Docker environments which were used to host the GLU.Engines and execute the GLU.USSD tests, 4 Nodes were set up involving 1 Manager and 3 Worker nodes.

Virtual Machine Sizes

EC2Virtual AWS SystemCPUMemory
Swarm Managert3.xlarge4 vCPU16 GiB
Swarm Node 1t3.xlarge4 vCPU16 GiB
Swarm Node 2t3.xlarge4 vCPU16 GiB
Swarm Node 3t3.xlarge4 vCPU16 GiB

System Versions


2nd test USSD with Integration Scenario Performance Test Results

Test CriteriaResult

Latency Scenario

Performance Testing was executed in GLU’s AWS Test Lab within a single VPC. This ensures little to no degradation in performance due to network communications.  Swarmpit was used to manage the Docker environments which supported the container running RabbitMQ.

The latency scenario was designed in such away to maximise performance where the end points were slow to respond with a high degrees of latency.  The performance testing was set up with horizontal scaling across 3 silos, with contention on the test stubs being managed through a load balancer.  Injection was carried out through a dedicated server for Jmeter, which was injecting USSD menu transactions into a GLU.Engine set up to distribute transactions to 3 separate Rabbit queues in a round robin fashion.

Virtual Machine Sizes

EC2Virtual AWS SystemCPUMemory
Decision Makert2.large2 vCPU8 GiB
USSD / Integration Enginest3.xlarge4 vCPU16 GiB
Test Stubt2.medium2 vCPU4 GiB
Swarm Managera1.2xlarge8 vCPU16 GiB
Swarm Node 1t3a.xlarge4 vCPU16 GiB
Swarm Node 2t3a.xlarge4 vCPU16 GiB

System Versions


Latency Scenario with USSD / Integration Performance Test Results

Test CriteriaNumber of SilosTPS Results
Latency 100msSilos 1350 TPS
Latency 100ms  Silos 3700 PS

GLU.Engines have the ability to be able to absorb increased latency if sufficient memory is allocated and throttle settings are adjusted to allow for the buffering of transactions. See Managing Load with Throttles.


Even at extreme high latency in excess of  3 seconds GLU.Engines will still deliver ±90TPS.

With latency reduced to of 100ms increases throughput to ±350TPS.

GLU.Engines scale in a near linear fashion. As additional performance is required additional servers can be added.

An increase in latency may necessitate additional memory allocation for the GLU.Engine to accommodate the buffering of transactions.

Environment Variables

It is possible to configure a set of variables such that the values of the Variable will change depending on the Environment which the GLU.Engine is run on.

An example of this is if you want to change a Slack channel which messages are sent to depending on whether you are deploying on a development environment or a production environment. It is possible to have a single variable name such as “slackKeyValue” with the channel keys for development and production being different.

Global Variables

Press the “Global Variables” button in the Environments tool, to access the Variable configuration screen.

The Global Variables screen shows the variables that exist. It is possible to “Add Variables”, and to modify and delete existing variables from this screen. Each Variable must have a unique name per Client, with a description of what the variable is used for.

If you add or modify a variable you will be presented with the ‘Edit Variable’ dialogue.

In this dialogue, you can define/modify the name of the variable and description. For each environment, you can set the value to be used. It is not necessary to enter values for Environments that are not used. If the value is left empty, then null will be present in the GLU.Engine when used in that environment. Once Variables have been set per environment, those variables will be used for each GLU.Engine Environment-specific build.

To use the environment variable in the integration use the name which was provided with the prefix “env_” … an example of how this is in use is given below.

/${header.env_slackKeyValue} … where the variable defined was slackKeyValue and the env_ is the prefix to identify the variable as an Environment Variable and the /${header. represents part of the parameter being passed to the URI.

It is also possible to use the Environment Variables from the pull-down in a Request Parameter in the Integration Builder. Any Environment Variables will be present in the pulldown box with the “env_” prefix.

Masking Environment Variables in the logs

See how the values are masked in the logs

Note: avoid using variables in Header, Body, or query sections endpoint calls, as they will not be encrypted when presented in the logs.

Using an Environment Variable in a Handler

Where an Environment Variable needs to have a condition applied and Action taken, when in the Integration Builder, and configuring the Handler, select the Environment Variable from the Parameter Name drop-down.

See the example below.

TCP/IP Connectors


TCP/IP is an abbreviation for Transmission Control Protocol / Internet Protocol. It is a set of protocols that define how two or more computers can communicate with each other. The protocol is effectively a set of rules that describe how the data is passed between the computers. It is an open standard so can be implemented on any computer with the appropriate physical attributes. 

Properties Tab

If Properties need to set for the TCP connector, for example for a TCP/IP connector to an HSM the key = textline must be set to the value = true as shown in the example below.

As another example, by default, TCP/IP Connectors are asynchronous. If you require the Connector to be synchronous, the key = synchronous must be set to the value = true.

Decoder / Encoder Configuration

As a final, slightly more complex example, messages sent over TCP/IP may contain a variable byte length header called the Variable Length Indicator (VLI), often 2 bytes. These 2 bytes precede every message sent to/from the TCP/IP End Point. Where this is the case Bytes 1-2 indicate the number of bytes in the message (excluding the first 2 bytes). The 2 bytes represent a 16bit unsigned integer in network byte order. Note that if a compressed message is being sent, the message will have to first be compressed, in order to determine its length, before being sent. As an example, suppose that you were to look at just the text (excluding the 2 byte header) making up an XML message from a particular example and that you then counted the characters and they happened to add up to 299 characters. If you took a scientific calculator (the one in Windows for example) and you typed in 299 with “Dec” (for decimal) selected, then you select “Hex”, the value that would be shown is “12B”, which means the same as 01 2B, which is exactly what one would expect to see for the first two bytes of the message if the message had been dumped to a file and then opened with a hex editor.

To handle such a requirement you can add properties as per screenshot below to configure the VLI settings for your connection. In this case the ‘Decoder Type’ is set to ‘StringDecoder’, the ‘Encoder’ is set to ‘LengthFieldPrepender’ and the Length is set to ‘2’.

In the screenshot below the above described Decoder / Encoder and Field Length settings are shown. Additionally you’ll see the TCI/IP property key = usebyteBuf is set to value = true … with this setting GLU will turn the message body into ByteBuf before sending it out. Just like an ordinary primitive byte array, ByteBuf uses zero-based indexing. It means the index of the first byte is always 0 and the index of the last byte is always capacity – 1.

Integration Builder – An Introduction

The Integration Builder is used to configure the APIs your GLU.Engine will expose, the Outbound Connectors and the Orchestration logic using Handlers that will direct the transaction flows.

When the GLU.Engine build is processed in the Build Manager tool, the Integration configurations are compiled using the Apache Camel Routes framework. This enables broad native support within GLU.Ware for the full spectrum of the Camel Route capabilities (e.g. Message Queues, Database connections, LDAP etc.).

Multiple integrations are supported. The GLU.Engine can be configured to connect to a multitude of systems, translating protocols between them as required. A single transaction might require data from multiple external systems in order to complete. GLU.Ware can validate a Request and collate the required data from different systems in order to complete the Request. Different outcomes of a transaction can be catered for with configurable ‘flows’ using ‘Handlers’.

All Integration flows start with an Inbound Connector (API) Request and end with a Response. Downstream of the Request/Response definition for a Transaction, the Integration Flow is defined in the Orchestration section. For each step in the Orchestration, calls can be passed to downstream systems via Outbound Connectors. The Outbound Connector options are created by configuration of the relevant Connectors using the ‘Connector Tool’. All Parameters (data) received for any End-Point are transformed or ‘un-marshalled’ into a GLU ‘Object-Model’ that is persisted for the duration of an individual transaction only. It’s from these un-marshalled parameters that subsequent Outbound Connector payloads (or the API Response) can be populated. These parameters can be converted to different protocol formats and / or simply reused at later steps in any flow.

Transaction Codes and Flow Codes

Each Transaction is identified by a Transaction Code which must be a unique ‘string’. It can be anything the Analyst desires, typically it will describe the API service being configured e.g. ‘BalanceEnquiry’.

Within the Orchestration each ‘leg’ is assigned a unique ‘Flow Code’ which similarly to the Transaction Code uniquely identifies each outbound call within the Orchestration Manager. These Flow Codes can be used to route transactions flows to specific steps in the flow i.e. Flows although defined chronologically do not necessarily follow the sequence in which they are defined.

A GUID is generated by the GLU.Engine for each Transaction processed by the GLU.Engine.

A GUID (Globally Unique Identifier) is a large, random number that is used to uniquely identify an transaction that the GLU.Engine processes. GUIDs are 128 bits long, which allows for a very large number of unique values. The GUID is labelled as the GLU_TXN_ID in the GLU.Engine logs. The GLU_TXN_ID’s are useful when one is tracing transactions in the logs. The use of GUIDs ensures that each transaction with it’s associate Transaction Code has a unique identifier.

The ‘Repair Integration’ Tool

The ‘Repair Integration’ tool at that top right of the Integration ‘tree’ is used to re-index the full tree structure of your integration. In the event that you have a configuration that has been imported or segments of integrations that have been cut or pasted into your tree, the indexing will need to be refreshed. This is simply done by clicking the ‘Repair Integration’ icon. In such situations where your config ‘index’ is mis-aligned, the configuration validations that run in the background and that flag config error warnings may flag warnings related to configuration issues that have been resolved. Using the ‘Repair Integration’ tool will clear such Warnings.

Search Integration Tool

The ‘Search’ tool at the top right of the Integration ‘tree’ is used to search and will retrieve matches from:
– The transaction code, the flow code.
– The parameter label, the parameter name, and the attribute name.
– The derived parameter label, the derived parameter name, and the derived parameter body.
– The static parameter label, the static parameter name, and the static parameter body.
– The handler label, and the condition value if applicable. e.g. when the parameter equals a <value>
– The value mapping.
– Any text in the request/response templates.
– Case is not considered, so if you search for something in capital letters both capital and lowercase will be found. As the font ‘case’ is not used for the search, the results will be displayed in Capital letters. For example, when searching for ‘response’ the results will be displayed as per the below screen

The search results appear as follows:

HTTP / RESTful Connectors

Configuring HTTP / RESTful Connectors

All GLU HTTP connectors use HTTP4 component.

HTTP4 is a new version of the Hypertext Transfer Protocol that aims to improve the performance, security, and scalability of web applications. It is based on the QUIC protocol, which uses UDP instead of TCP and supports multiplexing, encryption, and congestion control

HTTP Cross-Origin Resource Sharing

Host settings are the generic parts of the path e.g. http://localhost:9088/services

The Context Names configured in the Integration builder will result in a Outbound Connector Requests
that comprise the following parts: {host}{port}/{contextName}

Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any origins (domain, scheme, or port) other than its own from which a browser should permit loading resources.

To enable GLU CORS support, add ?enableCORS and allowed Headers to the Context Name in the Integration Builder.

1. Allow All Headers ?enableCORS=true&filterInit.allowedHeaders=*

2. Allow Specific Headers ?enableCORS=true&filterInit.allowedHeaders=x-channel-access-key,Access-Control-Allow-Headers,Access-Control-Allow-Methods,Access-Control-Allow-Origin


The Properties Tab is where Protocol specific Properties are defined. There are no HTTP or REST specific properties so these options are not applicable for such Connector types. For other types such for a SOAP Connector, the SOAP Properties such as WSDL Location, SOAP Context Service name etc. will be presented.

Swagger – OpenAPI 3.0


OpenAPI 3.0 is the latest name given to the previous Swagger standard, the market however is still widely familiar with and using the term ‘Swagger’ to refer to OpenAPI 3.0 – as such GLU refers to the GLU.Ware OpenAPI 3.0 as ‘Swagger’. Swagger Specification and API document are used interchangeably. Details on the OpenAPI 3.0 Standard are available here.

GLU.Ware has the ability to generate a Swagger standard based API document to describe the APIs in the GLU.Engine. The API document is compiled in the build process. GLU uses the API configuration (as defined in the GLU.Console) to define the method, schema and structure of the API, and it pulls in the associated API descriptions configured by the analyst in the Integration Builder. The API document is included in the GLU.Engine build such that when the JVM is run a web service will also run to host the Swagger web page to render the API document.

The GLU.Engine Swagger File can be accessed through {Engine_URL}:{Server Port}/swagger

As an example:


This will display the Open API 3.0 (Swagger) definition for the GLU.Engine APIs.

Download JSON for Swagger Specification

Included in the Swagger specification is a URL which can be used to download the full JSON for the swagger specification.

This JSON can be used to render the swagger definition in the GLU.Control API Manager and/or other swagger management tools.

Console API Control panel

The output of the API document generated by GLU will resemble the following sample.

The GLU.Console API Control Panel is used to configure the API document that will be generated.

The subsequent sections pertain to each of the labeled fields showcased in the API Control Panel screenshot provided above.

A – Swagger API Title

This is the title for the Swagger specification.

B – Swagger API description

This is the description of the API which should provide a description for all the API’s displayed on the Swagger specification and accessed in the GLU.Engine.

The format of this description is HTML.

See below for an example of the API description:

C – Swagger Contact email

This pertains to the contact details for the person responsible to support the exposed API, specifically the email address. Upon selecting this option on the screen, the associated email application will be triggered, and a new email will be created addressed to the provided email address.

D – Swagger API Terms of service URL

The URL to the terms of service for the API.


E – Swagger API Licence URL

The license information for the exposed API.


F – Swagger Groups

On the Swagger specification it is possible to group API transactions into sections. To do this use the ‘Manage Swagger Groups’ tool.

In the screenshot below you can see how APIs are grouped based on their Swagger Group associations.

G – Manage Swagger Servers

It is possible to configure URL settings to point at the GLU.Engine which contains the API transactions defined in the Swagger specification, this provides the ability to use the web service hosted swagger specification to test each API transaction.

Request Parameters

If samples have not been included in the API transactions configuration, then GLU will generate a schema for the API Request and Response parameters based on the configuration API “body” Request and Response parameters.

The schema is based on Parameter Types.

The table below shows how the parameters are mapped to the Swagger specification.

GLU.Console Parameter TypeGLU.Console Parameter definitionSwagger definitionGenerated in swagger
Dateincludes extra date format definitionstringYes
TextDEFAULTstringNo – default value isn’t included

See below example from the Swagger specification with the mapping.

Show in Swagger Doc: For each transaction there is a tick box which can be used to indicate if a section in the swagger specification should be generated. Tick the box to include in swagger specification, un-tick the box to leave out from swagger specification.

Sample messages for the Request payload as well as Success and Failure Samples for the Response payload can be defined. These where provided will be included into the API Document. When the samples sections are filled in, then these will override the definition of the schema from the request parameters. Instead the value defined in the sample field will be pushed to the swagger specification.

GLU Transaction Pattern

Within the Integration Builder, one uses the ‘Transactions Panel’ to Add Transactions. By clicking on ‘Add Transaction’, the Integration Builder will automatically create the Transaction ‘Pattern’ that is applicable to all Transactions.

All GLU.Ware Transactions follow this standardised repeating ‘Pattern’ whereby each transaction is defined or ‘anchored’ by the API definition. This comprises of the Inbound API Request that comes from any particular Initiating System, followed by the API Response that the GLU.Engine will return to that Initiating System.

Thereafter the Orchestration Manager is used to define what the GLU.Engine should do with the API Request payload once it has been received. Use the ‘Add Endpoint’ button to add ‘legs’ to your Orchestration configuration.

When you click ‘Add Endpoint’ the configuration pattern for Outbound Connectors is pre-populated for you. In this way the user is guided through the configuration of the Orchestration legs by populating the required configurations for each Outbound Request and Response to Endpoints that have been added to your configuration.

GLU.Ware Release Notes

At the bottom of all GLU.Console login screen the current version of the GLU.Console and the latest release date as shown. The history of GLU.Ware Release Notes since major Release 3.0 is provided below. The full history of Release Notes is available on request from GLU.Support.

Release notes – GLU.Ware – GLU.Console Release 3.3.0

Minor Feature Enhancements

  • GLUW-2613 In the GLU Engine Settings in Build manager we made the labels more descriptive. i.e. we indicated Max history value needs to be in days.
  • GLUW-3351 We have enriched the Build Error Messages.
  • GLUW-3884 Refined GLU.Engine meta data in logs to make more meaning full.
  • GLUW-4007 Added a New Function to Calculate ISO Field length and length of length to create described ISO Field.
  • GLUW-4243 Expanded documentation in GLU.Guide on ISO8583 – JPOS ignoreISOExceptions.

Bug Fixes

  • GLUW-4254 ISO issue with Compilation errors on q2 logs
  • GLUW-2373 Static Parameters: Action Cannot be empty
  • GLUW-3321 Errors in the logs – [array[]] is an ARRAY and Source: [trxArray[]] is a CLASS
  • GLUW-4063 What’s the char limit for Release Note? | RN special char | RN overwriting
  • GLUW-4163 If in full screen mode (button to right of XML JSON Converter) no popups show at all.
  • GLUW-4178 Build Manager: GLU.Engine Name missing from Download popup
  • GLUW-4251 Fixed a problem where a GE doesn’t start when its has 2 trx and each has scheduler
  • GLUW-4258 Addressed minot issue with the UX for Derived Parameter Management | Add Parameter Prompt

Release notes – GLU.Ware – GLU.Console Release 3.2.0

Minor Feature Enhancements

  • GLUW-4227 We created a new vendor specific application/json content type (PRAGMA)
  • GLUW-4175 We added the ability to in Global Variables to be able to specify if Global Variable is a String or Numeric value.
  • GLUW-4130 In the Scheduled function in the Integration builder, we have completed work on the Cron function. It is now possible to Schedule an API to trigger based on a Cron function We have moved the C switched on the Cron feature in the Schedule.
  • GLUW-4143 We have introduced a new feature to allow for a variable retry count in a response handler.

Bug Fixes

  • GLUW-4224 Setting the Password for a Redis connector needed to be fixed.
  • GLUW-4100 In Integration Builder we have optimised the screen responsiveness.
  • GLUW-4180 Getting error when we Build changes | No error in Repair for missing route To FlowCode

Release notes – GLU.Ware – Release 3.1.0

Major Feature Enhancements

  • GLUW-2077 GLU.Engine Configuration Control Multi-Environment support

We have introduced a new feature in the GLU.Engine aimed at addressing a potential risk associated with testing and deploying the engine in production environments. This release focuses on providing a solution that allows for direct changes to the GLU.Engine without requiring a complete rebuild, reducing the possibility of introducing untested modifications.

Key Changes and Enhancements:

  • Exposed a set of configuration files within the GLU.Engine system. Configuration files can be found in the “../engine/config/” directory.

List of Exposed Configuration Files:

  1. application.yml
  2. camel-context.xml
  3. flows.json
  4. iso8583
  5. loggingSetting.xml
  6. menu.json

By exposing these configuration files, system administrators and developers gain direct access to the GLU.Engine’s core settings. This enables them to make necessary adjustments without the need for rebuilding the engine, mitigating the risk of introducing untested changes during production.

We believe that this enhancement will significantly improve the flexibility and efficiency of managing the GLU.Engine system. Users can now make targeted modifications to the engine’s configuration files as needed, ensuring a streamlined development and deployment process.

Please note that any modifications made to these configuration files should be carefully tested and reviewed before deploying them in a production environment.

For more information on how to utilize and modify the exposed configuration files, please refer to our support team.

Minor Feature Enhancements

  • GLUW-3888 We have added a timestamp on the dialogue box for the application settings, so it is possible to see when the last change to these settings was made.
  • GLUW-3308 Further enhancements to the automatic generation of Swagger exposed on the SERVER PORT under the URL /swagger. Please note that the Swagger documentation remains compliant with the OpenAPI 2.0 specification. For more information on this please refer to Swagger – OpenAPI 3.0

Version 3.0.3 – Released: 22 February 2023

Major Feature Enhancements

  • GLUW-3019 We have refreshed the GLU.Guide and removed the requirement to access the GLU.Guide through a username and password so that it is available publicly to view. We have also enhanced the GLU.Console to provide a small window in the bottom corner which allows for a quick Guide assistance ‘in Console’. The old version of the GLU.Guide will be shutdown. The new Guider can be accessed on this link.

Minor Feature Enhancements

  • GLUW-3019 We have refreshed the GLU.Guide and removed the requirement to access the GLU.Guide through a username and password so that it is available publicly to view. We have also enhanced the GLU.Console to provide a small window in the bottom corner which allows for a quick Guide assistance ‘in Console’. The old version of the GLU.Guide will be shutdown.
  • GLUW-3869 We have added a new function CURRENT_NANO_TIME that returns the current time in nanoseconds.
  • GLUW-3870 We have standardise GLU Functions to be capital letters. However old lowercase syntax will also be supported.
  • GLUW-3878 We have updated the standard GLU Function formats to align the formats. Old formats will still be supported.
  • GLUW-3928 We have updated the ThrottleType 2 feature to support calling other APIs in the Integration, in addition to the existing functionality to call an orchestration Flowcode.
  • GLUW-3932 We have created a new function which will create a new GUID called GENERATE_GUID.

Bug Fixes

  • GLUW-3391 We have updated the DB Connector responses to make the Content-Type default to JSON.
  • GLUW-3502 We have removed the old ISO8583 Version from the GLU.Console.
  • GLUW-3775 We have addressed an anomaly related to deleting environments and how this is presented in the Build Manager.
  • GLUW-3821 We addressed a problem with copying Handlers from one transaction orchestration to another.
  • GLUW-3905 We fixed a problem where a large orchestration took a long time to delete.

Version 3.0.2 – Released: 19 January 2023

Minor Feature Enhancements

  • GLUW-3823 We have improved the response time to respond on an error, when a Docker container is pushed to a remote Docker repository.

Bug Fixes

  • GLUW-3814 Fixed the Context Name which didn’t allow a forward slash (/).
  • GLUW-3821 We fixed a copy/paste issue in the Integration Builder which was not working correctly for some fringe case scenarios.
  • GLUW-3871 We fixed the Paste button which was not being set correctly after a Derived Parameter was deleted.
  • GLUW-3875 Corrected an issue identified with Throttle Type 2 controls. Please contact support for more information if required on this fix.

Version 3.0.1 – Released: 7 December 2022

Major Feature Enhancements

  • GLUW-3639 We have added support for a new connector type. We now support GraphQL for outbound connections, for more information on this new connector type please refer to GraphQL Connectors.
  • GLUW-3764 We have also added the ability to generate automatically a Swagger (OpenAPI 3.0) Specification for the APIs in the GLU.Engine. For more details on how to configure your APIs so the descriptions, sample messages, and other ‘meta data’ about your APIs appear on the Swagger document please refer to Generate OpenAPI 3.0 (Swagger).

Minor Feature Enhancements

  • GLUW-1267 We in the process of enhancing our functionality related to the GLU.Engine’s ability to schedule (‘self-invoke’) API calls. This is the first ‘BETA’ release of this functional enhancement journey. The GLU.Guide will be updated to reflect these exciting new capabilities when they are fully released – no long ‘BETA’.
  • GLUW-1693 We have updated the GLU.Console to allow a single user to login multiple times. We believe this will help address the issue experienced by some users when a user’s session gets locked. In the roadmap we plan to add the ability to integrate the GLU.Console with 3rd party single sign-on services.

Bug Fixes

  • GLUW-3786 In the integration manager we fixed a problem with the description of a transactions where it looked like it was being duplicated across from one transaction to the next.
  • GLUW-3790 Fixed a problem with the ‘Search’ tool in the Integration manager, where it wasn’t truly accurate with what it found.
  • GLUW-3793 Fixed a problem in the integration manager in the orchestration connectors where the ‘Context Name’ would disappear when one deleted a character from the field.

Version 3.0.0 – Released: 20 October 2022

Major Feature Enhancements

  • GLUW-3316 We have updated all areas of the GLU.Console with a new look and feel. In some areas we have optimised positioning and utilisation of menus and buttons which we believe will improve the speed of creating integrations and USSD menus.
  • GLUW-3607 We have added a landing page from where you can quickly access latest integrations which have been worked on by every user in your organisation. It also provides quick access to key areas of GLU.Ware.

Minor Feature Enhancements

  • GLUW-3549 We have ratified AWS Elastic container register (ECR) for storing docker containers, See AWS ECR configuration.
  • GLUW-3551 Updated the Docker Settings as Password was limited to 255, we changed to support length ion 5000 characters. Specifically for AWS Elastic container service.
  • GLUW-2860 We have removed the “Jolokia Config Debug” from the GLU.Engine Settings Dialogue box.

Bug Fixes

  • GLUW-3631 Fixed ISO8583 issue caused when Connected state=false when trx is working. Should show =true if it’s connected.
  • GLUW-3630 Fixed issue when the ISO8583 log only shows request if there’s a response. Updated to always show both and print in order.
  • GLUW-3627 Connector Screen loads all Connectors.
  • GLUW-3591 Fixed issue with Invalid Node Description which is needed for ISO8583 field settings.
  • GLUW-3584 Fixed issue with generate parameters resulting in an invalid template warning & invisible template gets used.
  • GLUW-1614 Fixed an issue where repairing integration was breaking the Handler Routes None >> Many Request Handler.
  • GLUW-1140 Updated Request as Error messages was needed for mandatory ISO8583 fields (MTI etc.).

Release Fixes

  • GLUW-3720 We found that the GLu Console had a bug in it which was stopping the USSD Simulator from connecting the test USSD GLU.Engines in clients environments.
  • GLUW-3719 We found an issue with the latest release in respect to Throttle Type 2: Concurrent Requests using Thread Pools GLU.Engine would error when “Max Queue Size” was passed as 0. This has been corrected.

Fill the form and we’ll contact you shortly

    I agree with

    We uses cookies to make your experience on this website better. Learn more
    Accept cookies