Context Attributes

The execution context attributes store JSON-like data related to an execution, like user input, connector responses and configuration.

Context Attributes

The execution context attributes stores JSON-like data related to an execution, like user input, connector responses and configuration.
The attributes are used for sharing data between different DSL commands and making flow control decisions.

An attribute is accessed by its key using . for hierarchical access, e.g. client.address.city.
An attribute with no content is returned if there's no data for a given key.

Command namespace

Throughout a workflow execution, DSL commands store their results as context attributes using namespace as attribute key.

The whole attribute namespace is overwritten and any existing attributes stored within the namespace is lost.

e.g. a client route result will be stored in the application.client namespace.

route('client') {
   uri '/client'
   namespace application.client
}

Execution namespace

It is possible to get more details on the current execution using the execution namespace.

execution.uuid to get current execution UUID
execution.sharable to a sharable token used for starting the current execution

Setting using <<

In addition, it is possible to set context attributes directly using <<.

config.logo << 'http://logo.png'
products << [product1: "Product1", product2: "Product2"]

The << operator merges existing namespace with the specified payload, unlike using a command namespace.
It can be used for gathering data from multiple commands using the same namespace.

application << route('basic info')
application << route('advanced info')

Default values

The diamond operator can be used for providing a default value when an attribute is not set.

config.retries ?: 3

Lists

Attributes can store lists. It is possible to access list items using an item index as following:

list[index]

It is possible to use positive as well as negative index to access items from a list start and from a list end.

e.g. get a list item using an index

list << ['a', 'b', 'c']
list[0] == 'a'
list[2] == 'c'

e.g. get an item from a list end using a reverse index

list << ['a', 'b', 'c']
list[-1] == 'a'
list[-2] == 'b'

An attribute with no content is returned if an invalid index is used or an attribute does not store a list.

Attribute methods

  • isEmpty() determines is attribute is empty, e.g empty string, list, map
  • hasContent() determines is attribute has content

Remove attribute

To remove an attribute namespace use remove namespace DSL command.

remove client.test
remove 'toRemove'

Payload validation

It is possible to specify data structure and constrains for attribute payload, see Payload specification for more details.

The payload specification is then used for payload validation using the validate or require blocks.

  • validate is used in DSL commands, like route and exchange, to validate a command result.
  • require is used in a workflow definition to enforce data-constrains, like input attributes.

Require payload

Checks if a given attribute is set and matches a payload specification. Otherwise, the corresponding execution terminates with an error.
It can be used for enforcing attribute data-constrains during an execution, like checking a function input or workflow configuration.
Also, it is possible to use the require result for setting another attribute. The result only contains fields that are specified in the payload specification.

Example: check if input.test is not empty and set the test attribute:

input ->
    test << require(input.test)

Example: check if input contains firstname and lastname:

input ->
    require(input) {
        firstname
        lastname
    }

The current execution context is checked if attribute is omitted:

    config << 
        require {
            api {
                username
                password
            }
        }

Payload specification

A payload specification defines attribute payload data structure and constrains.

For key-value maps, it is possible to specify each key name and corresponding data constrains for values using the provided validators.
If no validator is specified, a required() validator is used by default.

You can use the following validators:

  • required() must not be empty,
  • optional() may or may not be empty,
  • string() must be a string,
  • number() must be a number,
  • list() must be a list,
  • truefalse() must be a boolean,
  • file() must be a file descriptor,
  • file mimeType must be a file descriptor and match the mime type, e.g. application/pdf, image, etc.,
  • oneOf value1, value2, ... must be one of the specified values,
  • regex ~/pattern/ must match a regular expression, the expression can be a string or a groovy regex pattern syntax.

A validate example:

validate {
    firstname
    lastname
    address {
            city { oneOf "Prague", "Paris" }
            zip { regex ~/^[0-9]{5}(?:-[0-9]{4})?$/ }
        }
    }
    age { number() }
    idFront { file 'image'}
}

See validate examples for more details.