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:
- Referencing an existing Gloop model property.
- Converting this property's value to upper case.
- Writing the upper-cased value to a new model.
- Converting the new model to JSON.
- 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:
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:
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 |
|
Below are some screenshots showing what the resulting Javascript script look like:
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 resideio.toro.gloop.object.builder.*
- where all Gloop object builders resideio.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 |
|
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:
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 tostdout
public String getErrorText()
- returns text sent tostderr
public String getExitCode()
- returns the exit codepublic 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):
The Script runner will write your script to a temporary file, then execute it as follows:
1 |
|
1 |
|
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
andstderr
in$output
, and$error
as mentioned). - Place a copy of the script's exit code in
$exitCode
. - Execute a command to output all
export
ed orset
variables to a new temporary file. - Read all
export
ed andset
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 export
ed.
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
export
s or set
s 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.