Flexiant Development Language (FDL) is a Lua based language that allows you to extend Flexiant Cloud Orchestrator.

Lua (pronounced 'loo-er') is an easy to use but powerful, fast, and lightweight, embeddable scripting language. More details on Lua can be found here. Flexiant Cloud Orchestrator uses Lua 5.2.


Learning Lua

This section will not teach you how to program in Lua. For resources on programming in Lua, we recommend you:

Introduction to FDL

You can write FDL either using the FDL Code Blocks Widget, or by cut and pasting from your favourite text editor. In this way you can create one or more FDL code blocks. For information about how Flexiant Cloud Orchestrator uses FDL code blocks as part of the billing system, see Products, Product Offers, and Billing.

You will notice that the system supplies one or more default FDL code blocks. These are marked read only (this is so that on an upgrade, we know we can replace them without overwriting any of your changes). However, you can duplicate them using the 'duplicate' button on the modal, and then edit the duplicate.

An FDL code block consists at the minimum of a register function. The register function returns references to zero or more other functions within the FDL code block, each of which describes an entry point.

Any example of a register function (from our default code block) is shown below:

function register ()
        return {
                "fixedResourceBilling",
                "serverAllocatedCPUBilling",
                "serverAllocatedRAMBilling",
                "sizeAllocatedBilling",
                "diskIOUsageBilling",
                "networkIOUsageBilling",
                "unitTopUpBilling",
                "fetchResourceBilling",
                "customerResourceAssetBilling",
                "subnetBillingIpV4"
        }
end

As you can see, it simply lists the names of the functions used as entry points.

Each entry point is called under two circumstances:

For example, the default code block provides FDL billing API entry points. These each implement a billing method. The first of these is set out below:

-- This is the most simplistic billing function, it will charge a fixed amount each time it is
-- invoked, and can be used with any product component.
function fixedResourceBilling(p)
        if (p == nil) then
                local confvalues = {getInitialUnitsDefinitionTable(), getRepeatUnitsDefinitionTable()}
                return {
                        ref="_fixedResourceBilling",
                        name = "Fixed billing for resources",
                        description = "Charge the same number of units in each billing period",
                        permittedPCT = nil,
                        configuredValues = confvalues,
                        api = "BILLING",
                        version = 1
                }
        end
        
        print ("Last Billing Time is : " .. p.lastBillingTime .. " Billing Factor is "..p.billingFactor)
        if (p.lastBillingTime == 0) then
                cunits = getInitialUnits(p.billingComp)
                if (cunits > 0.0) then
                        return {{units = cunits * -1, description="Initial charge"}}
                end
        else
                cunits = getRepeatUnits(p.billingComp)
                if (cunits > 0.0) then
                        return {{units = cunits * -1 * p.billingFactor , description = "Charge for period" }}
                end
        end
        return nil
end

Lines 4 to 16 inclusive deal with the situation where the entry point fixedResourceBilling is called with no parameters, and is hence being asked to describe itself. This does the following:

The remainder of the function deals with calculating how many units to bill for a given billing period in respect of a resource, i.e. it implements a billing method. In brief:

A longer example can be found at Example Billing Method.

Features of FDL common to all APIs

The following is common to all FDL APIs:

The range of Lua modules imported depends upon the API in use.

The FDL Billing API

The FDL Billing API has the following features:

FDL Billing API calls are called once per billing cycle per product component per resource. They should therefore execute quickly. Lua performs very efficient table lookups and arithmetic, and writing even moderately complex functions should not present a performance problem. You should however avoid attempting to perform operations which open external files, or do other time-consuming activities.

The FDL Trigger API

The FDL Trigger API has the following features:

PRE triggers are always done synchronously before a resource changes state. This means that PRE triggers can affect the time taken to perform an action. POST triggers are performed asynchronously and therefore should not affect performance. 

Improper use of triggers can severely disrupt your access to the platform, so be aware of the /etc/extility/local.cfg option JADE_ALLOW_TRIGGERS, which can be used to turn triggers on or off on a global basis. This value defaults to 1.

The following is a list of the various triggerTypes, and whether the trigger is initiated before (PRE) or after (POST) the initiating event:

Initiating eventtriggerTypePRE triggersPOST triggers
Creation of a resourceCREATEYesYes
Modification of a resourceMODIFYYesYes
Deletion of a resourceDELETEYesYes
Making an API callUSER_API_CALL or ADMIN_API_CALLYesYes

Jade exception

Exceptions thrown by triggers cannot initiate other triggers.

EXCEPTIONNoYes
Scheduled based on elapsed time intervalSCHEDULEDNoYes
Making a paymentPAYMENTYesYes
Purchasing unitsPURCHASEYesYes
Adding units to a customer's accountUNIT_TRANSACTIONNo Yes
Job state changeJOB_STATE_CHANGEYesYes
Authorisation of a customer accountAUTHYesYes
Server state changeSERVER_STATE_CHANGEYesYes
Server initialisation before metadata is passed to the booting serverSERVER_METADATA_UPDATEYesNo
Iteration of billing cycle (automatic)BILLINGNo Yes
Iteration of invoice collection cycle (automatic)COLLECTIONNo Yes

For more information about triggers, see Triggers. For an example of a complete trigger, see Example Trigger.

The FDL Payment API

The FDL Trigger API has the following features:

States affect Jade depending on what is returned, for example a payment can complete successfully, but if the payment provider returns SUSPEND, Jade will not recognise that the job has completed. As Jade will eventually decide that the job has taken too long to complete and time out, this can result in a situation where the job has failed when payment has been taken from the customer.