Skip to content

Toro Cloud Dev Center


Expression step icon

Supported languages

Gloop supports a variety of programming languages for script services, script steps, and set expressions, but since each language is different, they have their own specific features, behaviours, and limitations which are documented below. To help you get a better understanding of each language, included are examples which perform a very simple function, namely:

  1. Referencing an existing Gloop model property.
  2. Converting this property's value to upper case.
  3. Writing the upper-cased value to a new model.
  4. Converting the new model to JSON.
  5. Logging the JSON to the Martini INFO logger.

The new model will also be the output of the example service. Each section below will explain a little about the languages supported in Gloop, as well as an example service implementing the description above.

The image below shows the inputs and outputs of the Gloop script service:

Gloop script example Input and Output view

Gloop script example Input and Output view

Groovy

Groovy is the best supported scripting language in Gloop for the following reasons:

  • Groovy can be used to invoke the included functions in Martini, using Groovy's extension module functionality.
  • Groovy code can be dynamically typed.
  • Gloop models can be manipulated using simple dot notation, since they have a custom GroovyObject implementation.
  • Groovy can be used to manipulate Gloop objects directly.

Groovy compilation customizer

Don't forget that Groovy scripts are run through Martini's own compilation customizer.

As a result of Groovy having these features, the resulting code only contains two lines, as shown below:

Groovy script example service

Groovy script example service

Accessing Gloop specific variables

In Groovy, you can access the input, output, and Gloop Execution Context variables using reserved variables named $context, $outputContext, and $gloopExecutionContext.

GraalVM languages

GraalVM is a Java Virtual Machine that allows Java code to invoke code written in other languages including Javascript, Python, R, Ruby, and more. When using GraalVM languages in Gloop scripts, you can1:

  • Use dynamically typed code
  • Use dot notation to get and set Gloop model properties. This is possible because Gloop models are wrapped with a Gloop-specific implementation of GraalVM's org.graalvm.polyglot.proxy.ProxyObject interface.
  • Create objects using the language's native syntax, as they're later converted to Gloop models.

Gloop models in Graal

As stated, Gloop models are wrapped in a custom ProxyObject allowing simple dot notation for accessing Gloop model properties. If you need the model itself, you can access the _gloopModel property of a model, which will return the object returned from calling context.asValue(), using the model as the argument. Example:

1
2
var model = input.model._gloopModel;
console.log( model.asJson() );

Below are some screenshots showing what the resulting Javascript script look like:

Javascript Gloop script example service

Javascript Gloop script example service

Accessing reserved word variables

When a variable corresponds to a reserved word on the selected GraalVM language, it is prefixed with an underscore at runtime.

Accessing Gloop specific variables

In GraalVM scripts, you can access the input, output, and Gloop execution context variables using reserved variables named _context, _outputContext, and _gloopExecutionContext.

Kotlin

Kotlin is a cross-platform, statically typed, general-purpose programming language. Since it's statically typed, the Gloop APIs need to be used to manipulate Gloop models instead of using dot notation. As a result, Kotlin code can sometimes be more verbose than Groovy or Javascript. However, Kotlin scripts in Martini import all classes in the following commonly used packages:

  • io.toro.gloop.object.property.* - where all Gloop objects reside
  • io.toro.gloop.object.builder.* - where all Gloop object builders reside
  • io.toro.martini.* - where most of Martini's functions reside

Returning values from Kotlin scripts

Please note that Kotlin scripts can't explicitly return values. If you're using Kotlin for set, output, or validation expressions, the value returned will be the result from the last function called. An easy way to get around this is to invoke toString() on the object you would like to return as the last line of your script. For example:

1
2
var output = "Hello, Gloop!"
output.toString()

Validation scripts in Kotlin

Gloop uses a variable called val when executing validation expressions. Since this is a reserved word in Kotlin, Kotlin scripts should use _val instead. In fact, all variables that use Kotlin reserved words are prefixed with an underscore at runtime.

The screenshot below shows the sample service implemented in Kotlin:

Kotlin script example service

Kotlin script example service

Accessing Gloop specific variables

In Kotlin scripts, you can access the input, output, and Gloop execution context variables using reserved variables named _context, _outputContext, and _gloopExecutionContext.

Shell scripts

Gloop has the ability to execute Bash and Batch scripts2. The type of script supported depends on the operating system that Martini is running on. If it's running on Windows, then you will be able to write and execute Batch scripts; otherwise, Gloop assumes you have a shell installed that can execute Bash scripts.

When using Gloop to execute these types of scripts, it's important to remember that the script you write is first evaluated as a Groovy string. This means that variables in your Gloop context can be injected into the script using $ notation (for example, $myVariable). However, since Bash in particular uses $ heavily, care needs to be taken to ensure they're used and escaped properly.

stdout and stderr and exit data

If you would like a copy of the stdout or stderr text or exit code of your script, simply ensure Gloop has a compatible variable named $output, $error, or $exitCode. If Gloop finds these variables at runtime, they will be populated accordingly after your script has executed.

However, if your script returns an exit code other than 0, an exception will be thrown. This exception is of type io.toro.gloop.expression.TerminalExpressionRunnerException. This exception has the following 4 methods:

  • public String getOutputText() - returns text sent to stdout
  • public String getErrorText() - returns text sent to stderr
  • public String getExitCode() - returns the exit code
  • public String getErrorLineNumber() - returns the line number where the error occurred; will be set to -1 if the error line number could not be determined

Below is an example of a service that uses Bash to convert a string to upper case. Since it's not possible to set Gloop model properties from a Bash or Batch script, the data from the script is mapped elsewhere (in line 3 below):

Bash script example service

Bash script example service

The Script runner will write your script to a temporary file, then execute it as follows:

1
sh -c. <script file name.sh>;echo \$exitCode=$? > <export-file.txt>;export >> <export-file.txt>`
1
cmd.exe /V:ON /q /c <script file name.bat> & set $exitCode=!ERRORLEVEL! > <export-file.txt> & set >> <export-file.txt>

If you're familiar with the syntax, you may have noticed that for both bash and batch, it does the following:

  • Execute your script (keeping a copy of stdout and stderr in $output, and $error as mentioned).
  • Place a copy of the script's exit code in $exitCode.
  • Execute a command to output all exported or set variables to a new temporary file.
  • Read all exported and set variables, and map them back to Gloop.

If you would like to read in variable data from your Bash or Batch script, simply export (for Bash), or set (for Batch) accordingly. This can be seen on line 2 of the script in the screenshot above, where uppercased is exported. If the variable isn't already declared (as it is in line 1), then it will be lost. For validation expressions, make sure your script exports or sets a variable called gloop_result, as this is the variable value that's returned from these types of scripts. If this variable isn't set, null is returned instead.

Don't forget the shebang!

When writing Bash scripts, don't forget to prefix it with the preferred program loader using the shebang syntax. For *nix operating systems, this is usually #!/bin/sh, as shown in the screenshot above.


  1. LLVM does not support most of these features. 

  2. Batch scripts are files in Windows with a .bat extension.