ScriptEval
The Do It All Swiss Army Knife Valve
Introduction
Section titled “Introduction”Valve for evaluating scripts using the Java Scripting API (javax.script) and GraalJS/GraalVM.
Type of script supported (JavaScript/ECMA, Python, Ruby etc) is depending on the script engine used. By default this valve (and the examples) uses the graal.js engine with support for JavaScript.
For more information, see:
Configuration
Section titled “Configuration”| Name | Description | Default value | Mandatory | Expanded |
|---|---|---|---|---|
engine | The script engine to use. | "graal.js" | ||
source | The script to evaluate (Mandatory unless config.path is configured) | |||
path | Path to script to evaluate. |
{ "name": "ScriptEval", "config": { "source": "print('Hello, World!');" }}Context
Section titled “Context”During script evaluation the following objects are available in the script context:
| Name | Description |
|---|---|
request | The current request. Object is read-only and can not be modified. |
state | Object representing the current pipe state. |
session | Object representing the current session |
items | Object providing access to the current set of items. |
log | The current valve logger. |
context | The raw pipe context. Use only if objects above are not sufficient. Type: foss.pipes.valves.item.api.PipeContextItem |
Request parameters
Section titled “Request parameters”Pipe request parameters are accessed using the request object in script context:
// Read request parameter and assign to variablevar msg = request.message;
// Do stuff based on existence of a request parameterif (request.xxx) { // xxx is truthy}
// Do stuff based on the value of a request parameterif (request.username === "johnd") { // Parameter is of type string and has the value "johnd"}Pipe state can be accessed using the state script context object. Properties stored in state are available to all valves in a pipe and also included in the pipe response.
// Set or update a state property named 'name01'state.name01 = "value01";
// Read property from state and assignvar name01 = state.name01;
// Remove property from statedelete state.name01Session
Section titled “Session”The current session can be accessed using the session script context object.
Session has two reserved properties that can not be modified:
idtrace_id
// Read "reserved" session properties (can not modified)const sid = session.id;const tid = session.trace_id;
// Read property from sessionvar username = session.username;
// Set property in sessionsession.username = request.username;
// Remove property from statedelete session.username;Items is an API that provides access to the current item set. Using this API items can be created, loaded by id, removed and iterated.
Item objects returned by this api has an id property (reserved and read only) and an arbitrary number of other properties.
Note: Item properties are always of type string
// Check if items existif (!items.isEmpty()) { // At least one item exist}
// Get the number of itemsconst itemCount = items.size();
// Get first item// Note: items are not ordered, there is no guarantee which item is "first"// unless only one exist.const firstItem = items.first();
// Create a new item with id 'johnd'// Note: item id must be unique, if an item with specified id// already exist null is returnedconst item = items.create("johnd");item.created = true;
// Load specific item by id (returns null if not existing)const item = items.item("johnd")
// Get and set item propertiesvar value = item.value;item.value = "new value";
// Check if item with specific id existif (items.item('johnd')) { // Item exist}
// Remove property from itemdelete item.name;
// Get all items as an arrayconst array = items.all();if (array.length > 0) { // Not empty}
// Iterate current items with lambda// First lambda argument (id) is item id// Second lambda argument (item) is the actual itemitems.forEach((id, item) => { // Do stuff with item});
// Remove item (supports both item (object) and id (string))items.remove(id);items.remove(item);Logging
Section titled “Logging”Logging in scripts can be done using the standard console object:
console.log('log'); // Same as 'console.debug'console.trace('trace')console.debug('debug');console.info('info');console.warn('warn');console.error('error');or using the Fortified Logging API Logger object also supporting "printf" formatting:
log.trace('trace');log.trace('string: %s', "string arg");log.debug('debug');log.debug('int: %d', 99);log.info('info');log.info('boolean: %b', true);log.warn('warn');log.warn('Multiple args: %s (%d) %b', "string", 99, false);log.error('error');Troubleshooting
Section titled “Troubleshooting”Syntax error
Section titled “Syntax error”Bad script syntax result in a syntax error in the log (WARN) and a flow failure.
A syntax error typically looks like this and contains a location, description and the bad line:
SyntaxError: <eval>:43:24 Missing close quoteprint('Hello, World!''); ^Advanced
Section titled “Advanced”Java types
Section titled “Java types”To access java types in script use:
var FileClass = Java.type("java.io.File");or (backwards-compatible syntax):
var FileClass = java.io.File;var file = new FileClass("myFile.md");For more information regarding script interoperability with java, see: https://www.graalvm.org/reference-manual/js/JavaInteroperability/
Engine configuration
Section titled “Engine configuration”Script engine log can be configured using the following system property:
-Dpolyglot.log.file=<path>