Skip to main content
Version: Next

API Reference

Overview

This documentation describes the functionality that is available for configuration authors.

Please see the main sections

opscotch configuration model

The opscotch model is relatively straight forward, and uses repeated patterns - once you grasp these you should be able to understand the entire structure.

Here is the outline of the entire structure of the two configurations: the bootstrap and the workflow. Note that not every field is required, so be sure to check the detailed descriptions.

The bootstrap schema overview

[
{
"enabled" : true,
"agentPrivateKey": "",
"deploymentId": "",
"remoteConfiguration": "",
"remoteConfigurationAuth": "",
"remoteConfigurationTimeout" : 0,
"frequency": 0,
"reloadTimeout" : 0,
"keys" : [
{
"id" : "",
"keyHex" : "",
"metadata" :
"purpose" : "",
"type" : ""
}
],
"licenseHost" :
"licensePoolId" :
"packaging" : {
"additionalSigners" : [],
"packageId" : "",
"packagerIdentities" : [],
"requiredAdditionalSignerCount" : 0,
"requiredSigners" : []
},
"errorHandling": {
"enableLocalLogging": true,
"metrics": {
"enabled": true,
"routingToken": "",
"outputUrl": "",
"outputAuthorization": ""
},
"logs": {
"enabled": true,
"routingToken": "",
"outputUrl": "",
"outputAuthorization": ""
},
"redactionPatterns": [
""
]
},
"workflow" : {
"metricOutput": {
"enabled": true,
"routingToken": "",
"outputUrl": "",
"outputAuthorization": ""
},
"errorHandling": {
"enableLocalLogging": true,
"metrics": {
"enabled": true,
"routingToken": "",
"outputUrl": "",
"outputAuthorization": ""
},
"logs": {
"enabled": true,
"routingToken": "",
"outputUrl": "",
"outputAuthorization": ""
}
}
},
"allowExternalHostAccess": [
{
"authenticationHost" : true,
"id" : "",
"host": "",
"headers": {
"": ""
},
"allowList" : [
{
"method" : "",
"uriPattern" : ""
}
],
"data" : {}
}
],
"allowFileAccess": [
{
"id" : "",
"directoryOrFile" : "",
"patterns" : [""],
"LIST" : true,
"READ" : true,
"WRITE" : true,
"DELETE" : true
}
],
"allowHttpServerAccess": [
{
"id" : "",
"port" : 0,
"serveFromPackagedAsset" : {
"packagedAssetFileId": ""
}
}
],
"persistenceRoot" : "",
"data": {}
}
]

The workflow schema overview

{
"workflows": [
{
"enabled": true,
"name": "",
"steps": [
{
"enabled": true,
"debug": true,
"type": "",
"stepId": "",
"trigger" : {
"fileWatcher": {
"bootstrapFileId": "",
"eventSplitter": "",
"patterns": [ "" ],
"splitAtEnd": false
},
"http": {
"method": "",
"path": "",
"server" : ""
},
"timer" : {
"delay" : 0,
"period" : 0
},
"runOnce" : true
},
"authenticationProcessor": {
"script": "",
"resource": "",
"processors" : [
{
"script": "",
"resource": ""
"data": {}
}
],
"data": {}
},
"splitGenerator": {
"script": "",
"resource": "",
"processors" : [
{
"script": "",
"resource": ""
"data": {}
}
],
"data": {}
},
"urlGenerator": {
"script": "",
"resource": "",
"processors" : [
{
"script": "",
"resource": ""
"data": {}
}
],
"data": {}
},
"payloadGenerator": {
"script": "",
"resource": "",
"processors" : [
{
"script": "",
"resource": ""
"data": {}
}
],
"data": {}
},
"itemResultProcessor": {
"script": "",
"resource": "",
"processors" : [
{
"script": "",
"resource": ""
"data": {}
}
],
"data": {}
},
"resultsProcessor": {
"script": "",
"resource": "",
"processors" : [
{
"script": "",
"resource": ""
"data": {}
}
],
"data": {}
},
"httpStatusHandling": {
"" : {
"script": "",
"resource": "",
"processors" : [
{
"script": "",
"resource": ""
"data": {}
}
],
"data": {}
}
},
"httpConnectFailedProcessor": {
"script": "",
"resource": "",
"processors" : [
{
"script": "",
"resource": ""
"data": {}
}
],
"data": {}
},
"httpTimeout" : 0,
"singleThreaded" : "",
"persistenceFile" : "",
"data": {}
}
],
"data" : {},
}
]
}

Bootstrap JSON Schemas

JSON Schema in the Package:

Bootstrap

A configuration that is loaded into the agent at startup and determines how the agent loads the main configuration is loaded.

Please note that the bootstap file that is authored is an ARRAY of these objects ie:

[
{
"agentPrivateKey": ...
"deploymentId": ...
}
]

It will be provided to the agent as an argument, either via a base64 encoded json text or a path to a json file

JSON Properties

The following properties are available to set on the Bootstrap JSON schema.

agentPrivateKey
String
Required

Required The private key for the agent to decrypt the remote configuration.

This should be a base64 encoded private key in pkcs8 format

This is how to create an appropriate key

1. Create key pair
openssl genrsa -out keypair.pem 2048

2. Extract public part
openssl rsa -in keypair.pem -pubout -out public.key

3. Extract private part
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in keypair.pem -out private.key

4. Base64 the contents of this file
cat private.key | base64
{
"agentPrivateKey": "LS0tLS1CRUdJTiBQUklWQV...."
}
allowExternalHostAccess
Host
Optional

A list of Host objects that describes access to external http(s) services that can be called from the workflow configuration.

{
"allowExternalHostAccess": [
{
"id" : "myHost",
"host": "https://www.example.com",
"headers": {
"Content-Type": "application/json;charset=UTF-8",
"Accept": "application/json, text/plain, *\/*"
},
"allowList" : [
{ "method" : "GET", "uriPattern" : "/this/is/allowed.*"},
{ "method" : "POST", "uriPattern" : "/this/.*\/allowed"}
],
"data" : {

}
}
}
]
allowFileAccess
FilePermitter
Optional

A list of File Permitters that describe access to files and directories.

When a directory is specified the permissions apply to all files in that directory.

Available permissions are:

  • LIST
  • READ
  • WRITE
{
"allowFileAccess": [
{
"id" : "myTxtFiles",
"directoryOrFile" : "/path/to/a/directory",
"pattern" : ".*\\.txt",
"READ" : true
}
]
}
allowHttpServerAccess
HttpServerPermitter
Optional

A list of Http Server Permitters that describe access https servers running in the agent.

This is a configuration for starting HTTP servers in the agent.

{
"allowHttpServerAccess": [
{
"id" : "myHttpServer",
"port" : 1234
}
]
}
data
Object
Optional

A JSON Object for adding properties.

These properties will be merged with the WorkflowConfiguration.data configuration field and be available to all child elements in the main configuration tree.

{
"data": {
"somedata" : {
"abc: 123
},
"someotherdata" : [ 1, 2, 3]
}
}
deploymentId
String
Required

Required A Service Provider defined value that must be unique per deployed agent configuration.

This property is used by Service Provider downstream processor to enrich the transmitted data.

{
"deploymentId": "a7d2f8"
}
enabled
Boolean
Optional

Disable is bootstrap by setting enabled : false

Defaults to true

{
"enabled": false
}
errorHandling
ErrorHandling
Optional

Determines the behavior of error handling while loading the main configuration

{
"errorHandling": {
...
}
}
frequency
Integer
Optional

When using a URL Bootstrap.remoteConfiguration, setting this property will set the polling period in milliseconds

Defaults to 60000 (60 seconds)

{
"remoteConfiguration": "http://www.example.com",
"remoteConfigurationAuth" : "xodsjfujrhdjfk",
"frequency" : 60000
}
hosts
OldHost
Optional

DEPRICATED: use allowExternalHostAccess

A set of named Host objects. This allows the bootstrap to define http(s) host that can be called from the main configuration.

{
"hosts": {
"mynamedhost": {
"host": "https://www.example.com",
"stepId": "example.com",
"headers": {
"Content-Type": "application/json;charset=UTF-8",
"Accept": "application/json, text/plain, *\/*"
},
"allowlist" : [
["GET", "/this/is/allowed.*"],
["POST", "/this/.*\/allowed"]
],
"data" : {

}
}
}
}
keys
Key
Optional

Optional List of keys made available to the agent.

The set of keys will be made available to the agent for cryptographic functions like encryption and signing.

The keys can be used by the packaging subsystem and can also be made available in workflows via the crypto context

licenseHost
String
Optional

An http(s) host running an opscotch licensing app where licenses can be obtained from.

Defaults to "http://localhost:39576" which is expected to be the running opscotch with an embedded licensing app.

{
"licenseHost" : "https://your.opscotch.license.app"
}
licenseHostPoolId
String
Optional

A licensing pool id configured on the opscotch licensing app.

Defaults to "default".

{
"licenseHostPoolId" : "anotherPool"
}
packaging
Packaging
Optional
persistenceRoot
String
Optional

Defines the filesystem storage root for persistence

{
"persistenceRoot": "/storage"
}
reloadTimeout
Integer
Optional

Defines the maximum time in milliseconds to wait for a workflow to terminate running flows before loading a new version

Defaults to 10000 (10 seconds)

{
"reloadTimeout": 1000
}
remoteConfiguration
String
Required

Required A URL or file path to the main configuration.

The main configuration does not exist, the agent will wait until it becomes available. When referencing a file, its important to remember that the path is relative to the opscotch working directory, NOT the bootstrap file

{
"remoteConfiguration": "http://www.example.com",
"remoteConfigurationAuth" : "xodsjfujrhdjfk",
"frequency" : 60000
}
remoteConfigurationAuth
String
Optional

When using a URL remoteConfiguration, setting this property will set the "Authorization" header

{
"remoteConfiguration": "http://www.example.com",
"remoteConfigurationAuth" : "xodsjfujrhdjfk",
"frequency" : 60000
}
remoteConfigurationTimeout
Integer
Optional

When using a URL remoteConfiguration, setting this property will set the http timeout period in milliseconds

The remoteConfigurationTimeout must be less than the frequency

Defaults to 1000 (1 second)

{
"remoteConfiguration": "http://www.example.com",
"remoteConfigurationAuth" : "xodsjfujrhdjfk",
"frequency" : 60000,
"remoteConfigurationTimeout" : 1000
}
workflow
WorkflowOutputs
Optional

Determines metric and log outputs for the workflows

{
"workflow": {
...
}
}

ErrorHandling

A configuration defining if and how to send error metrics or log to a remote system

JSON Properties

The following properties are available to set on the ErrorHandling JSON schema.

enableLocalLogging
Boolean
Optional

Enable or disables logging of errors and information to the agent standard out

Defaults to true

{
"enableLocalLogging": true
}
logs
Output
Optional

Defines how error logs are sent to a remote system.

Error logs are brief messages from a fault in the agent and are sent to a remote system for attention.

Error log configuration only apply to the process configuration they are defined for. For example the Bootstrap.errorHandling defines error handling while loading configurations, and the WorkflowConfiguration.errorHandling defines error handling during the execution of configuration steps.

{
"logs": {
...
}
}
metrics
Output
Optional

Defines how error metrics are sent to a remote system.

Error metrics represent a fault in the agent and are sent to a remote system for attention.

Error metric configuration only apply to the process configuration they are defined for. For example the Bootstrap.errorHandling defines error handling while loading configurations, and the WorkflowConfiguration.errorHandling defines error handling during the execution of configuration steps.

{
"metrics": {
...
}
}
redactionPatterns
String
Optional

Defines regex patterns to apply redaction to log statements

Log statements from will have these redaction patterns applied before logging.

{
"redactionPatterns": [
"[0-9]+"
]
}

FilePermitter

Describes controlled access to files and directories.

Regular Expressions can be used to further restrict access to specific files.

JSON Properties

The following properties are available to set on the FilePermitter JSON schema.

DELETE
Boolean
Optional

When true files will be deletable.

Defaults to false

{
"DELETE": true
}
directoryOrFile
String
Optional

A path to a directory or file.

The directory or file does not need to exist. If a directory is specified it must end in a / (or the OS file separator)

Directory example:

{
"directoryOrFile": "/path/to/directory/"
}

File example:

{
"directoryOrFile": "/path/to/directory/or/file"
}
id
String
Optional

An id that must be unique to this bootstrap.

Use this id in the workflow step file trigger.

{
"id": "myTextFiles"
}
LIST
Boolean
Optional

When true files will be listable.

Defaults to false

{
"LIST": true
}
patterns
String[]
Optional

A list of (Java) Regular Expressions that can be used to further restrict access to files in the directory

{
"patterns": [
".*\\.txt$",
".*\\.log$"
]
}
READ
Boolean
Optional

When true files will be readable.

Defaults to false

{
"READ": true
}
required
Boolean
Optional

When true the file or directory must exist otherwise an error is thrown.

Defaults to false

{
"required": true
}
WRITE
Boolean
Optional

When true files will be writable.

Defaults to false

{
"WRITE": true
}

Host

A HTTP(S) host that the agent/app is expected to communicate with. Apps CAN NOT call any host not referenced by a Host record.

JSON Properties

The following properties are available to set on the Host JSON schema.

allowList
HostAllow
Optional

A list of allowed paths that may be called on this host.

A list of regex that will be matched to URL path. Matching results will be allowed, non-matching results will be blocked and logged.

{
"allowList": [
{ "method" : "GET", "uriPattern" : "/this/is/allowed"},
{ "method" : "POST", "uriPattern" : "/this/.*\/allowed"}
]
}
authenticationHost
Boolean
Optional

When set to true the host can only be used by an authentication context, when set to false (default) the host can only be used by a non-authentication context.

{
"authenticationHost": true
}

Defaults to false

data
Object
Optional

A JSON Object with Additional properties that will accessible during authentication steps.

You can use environment variables in the form of ${NAME} anywhere in the data structure: the environment variable will be substituted prior to parsing.

Strings in the data structure (after environment variable substitution) can be encrypted using the opscotch packager. Values will be decrypted at access time.

Encryption is done via the packaging tool and requires the agent public key.

{
"data": {
"somedata" : {
"abc: 123
},
"someotherdata" : [ 1, 2, 3],
"someencryptedstring" : {
"abc" : "some encrypted value"
}
}
}
headers
String
Optional

A object of HTTP headers to be sent with every call.

{
"headers": {
"Content-Type": "application/json;charset=UTF-8",
"Accept": "application/json, text/plain, *\/*"
}
}
host
String
Required

Required A URL that is used as the base for constructing URLs to call.

{
"host": "https://www.example.com:8080"
}
id
String
Required

Required A unique string that identifies this host in other configurations.

{
"id": "myHost"
}

HostAllow

Defines allowed http access patterns

JSON Properties

The following properties are available to set on the HostAllow JSON schema.

method
String
Optional

HTTP Method to match on. One of:

  • GET
  • HEAD
  • POST
  • PUT
  • DELETE
  • OPTIONS
  • PATCH
{
"method": "GET"
}
uriPattern
String
Optional

Regex pattern to match on the URI.

{
"uriPattern": ".*"
}

HttpServerPermitter

Creates an HTTP server bound to the specified port.

Steps for this bootstrap using a http trigger can bind to this http server.

A special feature is being able to serve static content from a zip file - see serveFromPackagedAsset

JSON Properties

The following properties are available to set on the HttpServerPermitter JSON schema.

id
String
Required

Required A unique string that identifies this http server in other configurations.

{
"id": "myAPI"
}
port
Integer
Required

Required A port on the host that this http server will bind to. Normal port binding rules apply.

{
"port": 1234
}
serveFromPackagedAsset
ServePackagedAsset
Optional

Describes how to serve content from a zip file.

{
"serveFromPackagedAsset": {
...
}
}

Key

Defines a cryptographic key made available to agent internal cryptographic functions (encryption and signing) and also to workflow/app cryptographic functions.

Keys must have a specified purpose and type that imply the required key length, which is verified before use.

Keys defined in the bootstrap are made available to the workflow context and also to internal agent operations like packaging and security.

Keys can be added to a workflow context, during a workflow context, via the crypto context.registerKey(...). Keys added during a workflow context are removed when that context ends.

Once a key is added, it cannot be retrieved or removed.

When using keys, they can be selected by id or purpose/type. Keys are only ever used by reference and are never readable in the workflow context.

See the crypto context for more information.

JSON Properties

The following properties are available to set on the Key JSON schema.

id
String
Required

Required A unique identifier used to reference a specific key

keyHex
String
Required

Required The hex encoded key

metadata
String
Optional

Additional metadata used solely for ease of key management in the bootstrap. This metadata is not loaded into the agent.

purpose
String
Required

Required The intended purpose of the key.

The purpose is used to filter and verify the key properties for the intended usage.

Values can be one of:

  • sign: used for signing or signing verification
    • secret key length: 64
    • public key length: 32
  • authenticated: used for mutually authenticated encryption
    • secret key length: 32
    • public key length: 32
  • symmetric: used for symmetric encryption
    • secret key length: 32
  • anonymous: used for anonymous public key encryption
    • secret key length: 32
    • public key length: 32
type
String
Required

Required public or secret corresponding to the purpose

OldHost

DEPRICATED This is the old host structure and has been replaced with the new host structure. See allowExternalHostAccess

A HTTP(S) host that the agent is expected to communicate with.

This only applies to customer specific hosts, not to Service Provider hosts.

Hosts are defined in Bootstrap.data and WorkflowConfiguration.data

JSON Properties

The following properties are available to set on the OldHost JSON schema.

allowlist
String[]
Optional

A list of allowed paths that may be called on this host.

A list of regex that will be matched to URL path. Matching results will be allowed, non-matching results will be blocked and logged.

{
"allowlist": [
["GET","/this/is/allowed"],
["POST","/this/.*\/allowed"]
]
}
authenticationHost
Boolean
Optional

When set to true the host can only be used by an authentication context, when set to false (default) the host can only be used by a non-authentication context.

{
"authenticationHost": true
}

Defaults to false

data
Object
Optional

A JSON Object with Additional properties that will accessible during authentication steps.

You can use environment variables in the form of ${NAME} anywhere in the data structure: the environment variable will be substituted prior to parsing.

Strings in the data structure (after environment variable substitution) can be encrypted using the opscotch packager. Values will be decrypted at access time.

Encryption is done via the packaging tool and requires the agent public key.

{
"data": {
"somedata" : {
"abc: 123
},
"someotherdata" : [ 1, 2, 3],
"someencryptedstring" : {
"abc" : "some encrypted value"
}
}
}
headers
String
Optional

A object of HTTP headers to be sent with every call.

{
"headers": {
"Content-Type": "application/json;charset=UTF-8",
"Accept": "application/json, text/plain, *\/*"
}
}
host
String
Required

Required A URL that is used as the base for constructing URLs to call.

{
"host": "https://www.example.com:8080"
}

Output

Configuration for how to send data to a remote system.

JSON Properties

The following properties are available to set on the Output JSON schema.

enabled
Boolean
Optional

Enables or disables the sending of data. Defaults to false

{
"enabled": true
}
outputAuthorization
String
Optional

Set the "Authorization" header.

{
"outputAuthorization" : "xodsjfujrhdjfk"
}
outputUrl
String
Required

Required The URL that data is transmitted to.

{
"outputUrl": "http://www.example.com"
}
persistenceRoot
String
Optional

If set, defines the location to store output queue files

{
"persistenceRoot" : "/tmp/output-queues"
}
routingToken
String
Required

Required A Service Provider defined value that must be unique per deployed agent.

This property is used by Service Provider downstream processor to direct and enrich the transmitted data.

{
"routingToken": "dogurj"
}

Packaging

Packaging applies required security constraints to package (app) loading.

Packages can be signed by the packagers and the signatures can be verified before loading. Signatures can be required or optional, and can have a required number of signatures.

Packages can be encrypted with mutually authenticated encryption meaning that the packager added keys specifically for this deployment, and this deployment has the matching key.

JSON Properties

The following properties are available to set on the Packaging JSON schema.

additionalSigners
Key
Optional

Optional Used in conjunction of the requiredAdditionalSignerCount, define a list of additional signers by id that can also sign the package. The id must match a single key id in keys. This property is used to provide a pool of additional signers to sign the package.

{
"keys" : [
{
"id" : "trusted-party-1",
"purpose" : "sign",
"type" : "public",
"keyHex" : "..."
},
{
"id" : "trusted-party-1",
"purpose" : "sign",
"type" : "public",
"keyHex" : "..."
}
],
"packaging" : {
"additionalSigners": [
{
"id": "trusted-party-1",
"description" : "A trusted party"
},
{
"id": "trusted-party-2",
"description" : "Another trusted party"
}
]
}
}
packageId
String
Optional

Optional However, if using opscotch packaging app then its required. The packageId must match the packageId in the packaged file.

This property is used to ensure only the packageId specified is laoded.

{
"packageId": "a7d2f8"
}
packagerIdentities
String
Optional

Optional A list of public key ids of packaging identities that proves the authenticity of the package. The private key for this package deployment must be in the keys list.

Note that a package can be encrypted with multiple keys and each decryption key pair must be present in the keys list.

{
"packagerIdentities": [
"trusted-party-1", "trusted-party-2"
]
}
requiredAdditionalSignerCount
Integer
Optional

Optional Set the number of additional signers required from the additionalSigners list.

This property is used to ensure that the packageId is signed by a minimum number of specified keys.

Defaults to 0

 {
requiredAdditionalSignerCount : 2
}

requiredSigners
Key
Optional

Optional Define a list of required signers by id. The id must match a single key id in Bootstrap.keys

This property is used to ensure that the package is signed by specified keys

{
"keys" : [
{
"id" : "trusted-party-1",
"purpose" : "sign",
"type" : "public",
"keyHex" : "..."
},
{
"id" : "trusted-party-1",
"purpose" : "sign",
"type" : "public",
"keyHex" : "..."
}
],
"packaging" : {
"requiredSigners": [
{
"id": "trusted-party-1",
"description" : "A trusted party"
},
{
"id": "trusted-party-2",
"description" : "Another trusted party"
}
]
}
}

ServePackagedAsset

Defines how to serve static files from a packaged asset (zip file)

JSON Properties

The following properties are available to set on the ServePackagedAsset JSON schema.

packagedAssetFileId
String
Optional

Identifies a FilePermitter in the bootstrap to serve from.

THe FilePermitter should be a path to a zip file.

{
"packagedAssetFileId": "myZipFile"
}

WorkflowConfiguration

The configuration that describes the main activities of the agent

JSON Properties

The following properties are available to set on the WorkflowConfiguration JSON schema.

data
Object
Optional

A JSON Object for adding properties.

These properties will be merged with the Bootstrap.data configuration field and be available to all child elements.

{
"data": {
"somedata" : {
"abc: 123
},
"someotherdata" : [ 1, 2, 3]
}
}
workflows
Workflow
Required

Required A list of Workflow describing the agent tasks

{
"workflows" [
...
]
}

WorkflowOutputs

Determines the behaviour of error handling and metrics for the workflow

JSON Properties

The following properties are available to set on the WorkflowOutputs JSON schema.

errorHandling
ErrorHandling
Optional

Determines the behavior of error handling while running the main configuration

{
"errorHandling": {
...
}
}
metricOutput
Output
Optional

Metrics represent a data point that is interesting, generated by the agent and are sent to a remote system for analysis.

{
"metricOutput": {
...
}
}

Workflow JSON Schemas

JSON Schema in the Package:

FileWatchingTrigger

Defines a trigger that fires when new lines are added to a file.

Each event (split by the lineSplit property) will be sent to the step processor. A sample event:

{
"log": {
"file": {
"path": "/path/to/file.txt"
},
"offset": 4130
},
"message": "this is a line from a file",
"input": {
"type": "log"
},
"host": {
"name": "hostname",
"ip": "[fe80:0:0:0:a6d7:feea:f601:902%wlp1s0, 192.168.0.27]"
},
"agent": {
"type": "opscotch",
"version": "3.0.0"
},
"ecs": {
"version": "1.12"
}
}
JSON Properties

The following properties are available to set on the FileWatchingTrigger JSON schema.

bootstrapFileId
String
Optional

Defines the allowed file access from the bootstrap

This must match an id in a bootstrap.allowFileAccess.id

{
"bootstrapFileId": "myTestFiles"
}
eventSplitter
String
Optional

Defines the (Java) regular expressions used to split events.

The delimiter will be present on the event message. The events that are collected from this trigger will be passed into the step processor as a list. The event has select field from the ECS for base, log, host, agent.

{
"eventSplitter": "\\n"
}
noTrace
Boolean
Optional

When true these executions will be omitted from tracing (monitoring)

patterns
String[]
Optional

A list of (Java) regular expressions used for file selection

{
"patterns": [
".+\\.txt$",
".+\\.log$"
]
}
splitAtEnd
Boolean
Optional

When true the delimiter is at the end of the line, when false the delimiter will be at the start of the line.

Defaults to true

{
"splitAtEnd": false
}

HttpRequestTrigger

Describes how to bind to a http request

JSON Properties

The following properties are available to set on the HttpRequestTrigger JSON schema.

method
String
Optional

The HTTP method to listen for.

Defaults to GET

{
"method": "POST"
}
multiPartUploadByteLimit
Integer
Optional

Limits multipart uploads to this number of bytes

NOTE: setting this enables multipart uploads for this endpoint

noTrace
Boolean
Optional

When true these executions will be omitted from tracing (monitoring)

path
String
Optional

A regular expression that matches against the URI path

{
"path": "/api/.*"
}
server
String
Optional

Identifies the bootstrap http server to listen to

{
"server": "myAPI"
}

JavaScriptSource

A JavaScript that is executed during the processing of a Step

JSON Properties

The following properties are available to set on the JavaScriptSource JSON schema.

data
Object
Optional

A JSON Object for adding properties.

Used to pass parameters and data to the script.

These properties will be merged with all other data fields in the json path, available to the step script elements.

{
"data": {
"somedata" : {
"abc: 123
},
"someotherdata" : [ 1, 2, 3],
}
}
resource
String
Optional

A file path to the script to execute.

Must be supplied if JavaScriptSource.script is not supplied

{
"resource": "scripts/myscript.js"
}
script
String
Optional

The script to execute.

A json-escaped script. Must be supplied if JavaScriptSource.resource is not supplied

{
"script": "console.log(\\"hello world\\");"
}

JavascriptProcessor

JSON Properties

The following properties are available to set on the JavascriptProcessor JSON schema.

processors
JavaScriptSource
Optional

A list of JavaScriptSource that will be executed in order

{
"processors" : [
{
"resource" : "..."
},
{
"resource" : "..."
}
]
}

PersistentQueueParams

NOT IMPLEMENTED

JSON Properties

The following properties are available to set on the PersistentQueueParams JSON schema.

maxFileBytes
Integer
Optional

HARD CODED TO 5MB

maxMemoryBytes
Integer
Optional

HARD CODED TO 1MB (1024 * 1024)

queuefilePrefix
String
Optional

HARD CODED TO persistenceFile + "-queue-" + deploymentId + "-" + stepId

Step

The Step is the primary configuration item for the agent configuration.

This configuration describes how to perform a single step or action in a Workflow.

There are different types of steps, however they all have the same execution structure:

  • Prepare
  • Execute
  • Process

Steps take three forms of input:

  • The response from a call to a Host (context.getMessageBodyAsString())
  • The message passed from another Step (context.getPassedMessageAsString())
  • Data from the configuration (context.getData())

The different types of Steps allow for specialised behaviour:

  • "scripted" type: this is the default type with the following flow:

    1. Optionally generate a URL (urlGenerator)

    2. Optionally (requires a url to have been set) generate a payload (payloadGenerator)

    3. Optionally perform authentication steps (authenticationProcessor, call other steps to perform authentication)

    4. Optionally call out to a named Bootstrap Host with the generated URL and payload

    5. Optionally handle specific HTTP status codes with httpStatusHandling

      OR

    6. Process the response or perform after-call processing (resultsProcessor)

      Perhaps:

      • Send a message to another Step
      • Produce some metrics
  • "scripted-split-aggregate" type: this is a modified "scripted" type that has the following workflow of:

    1. transforming the input into a list (splitGenerator)

    2. calling a URL with each item in the list:

      1. Optionally generate a URL (urlGenerator)

      2. Optionally (requires a URL to have been set) generate a payload (payloadGenerator)

      3. Optionally perform authentication steps (authenticationProcessor, call other steps to perform authentication)

      4. Optionally call out to a named Bootstrap Host with the generated URL and payload

      5. Optionally handle specific HTTP status codes with httpStatusHandling

        OR

      6. Optionally Process each item's response (itemResultProcessor)

      7. Collect the result into a response list

    3. The list of collected responses can then be processed and per normal (resultsProcessor)

      Perhaps:

      • Send a message to another Step
      • Produce some metrics

      Please note that in the case that one of the HTTP requests fail, it is your responsibility to handle this case by using the httpStatusHandling, itemResultProcessor, and resultsProcessor

  • "scripted-auth" type: this is identical to "scripted" except that it has an alternative javascript context - it is not allowed to send metrics or call to non-authentication steps, but has access to the bootstrap data which may contain secrets.

  • "httpFile" type: this is a specialized step that serve static content from a zip file by mapping a url path into a zip file path. This type REQUIRES a http trigger to be defined, an only allows GET requests

At least one step in a Workflow will define a Step.trigger that will trigger the start of Workflow processing.

These forms of input and different type allows for the construction of flexible pipelines that should be sufficient to perform most tasks.

JSON Properties

The following properties are available to set on the Step JSON schema.

authenticationProcessor
JavascriptProcessor
Optional

This processor runs directly before an http call. It is not valid to have an authenticationProcessor without an urlGenerator. This processor is expected to modify the context, generally by calling authentication steps and/or applying headers.

{
"authenticationProcessor": {
...
}
}
data
Object
Optional

A JSON Object for adding properties.

Used to pass parameters and data to the JavaScriptSource elements.

These properties will be merged with all other data fields in the json path, available to the step JavaScriptSource elements.

{
"data": {
"somedata" : {
"abc: 123
},
"someotherdata" : [ 1, 2, 3],
}
}
debug
Boolean
Optional

Enables or disables the debug logs for this step. Defaults to false.

{
"debug": true
}
enabled
Boolean
Optional

Enables or disables the execution of this step. Defaults to true.

{
"enabled": true
}
httpConnectFailedProcessor
JavascriptProcessor
Optional

Defines how to handle HTTP connection failures using a standard processor

{
"httpConnectFailedProcessor": {
...
}
}
httpStatusHandling
JavascriptProcessor
Optional

A set of JavascriptProcessor to process depending on the http status.

The key is the HTTP status either as a discrete number ie "401" or a range "400-499" and the value is a (standard processor)(#JavascriptProcessor).

When a status code matches a status handler and the handler is executed the resultProcessor or itemProcessor will not be executed.

Note: When supplying ANY httpStatusHandling you will also need explicitly declare success codes ie 200 as the resultsProcessor will not be called

{
"httpStatusHandling": {
"301-302" : {
...
},
"401" : {
...
}
}
}
httpTimeout
Integer
Optional

Set the http timeout period in milliseconds

Defaults to 10000 (10 seconds)

{
"httpTimeout" : 10000
}
itemResultProcessor
JavascriptProcessor
Optional

When using Step.type "scripted-split-aggregate", defines if and how to process items before they're added to the list.

{
"itemResultProcessor": {
...
}
}
payloadGenerator
JavascriptProcessor
Optional

Defines how to generate the call payload, including setting headers.

This requires the urlGenerator to be present and will throw a validation exception. If this processor is not used, then the HTTP body will be removed.

{
"payloadGenerator": {
...
}
}
persistenceFile
String
Optional

Defines a cache/memory/key-value store that the Step has access to.

Required if using various functions. If required and not defined an error will be logged

{
"persistenceFile": "persistenceFile.data"
}
resultsProcessor
JavascriptProcessor
Required

Required Defines how to process the result of the call to the host. Note: You might setup result processing via the httpStatusHandling property - you will still need to define a resultsProcessor though, even if it is an empty string.

{
"resultsProcessor": {
...
}
}
singleThreaded
String
Optional

Determines the behaviour when the step is called while it's still executing.

Options are:

  • "none" - step is not single threaded and can be run simultaneously (default)
  • "return" - step is single threaded: if the step is already running, any calls to start the step will return immediately without running

Future options are likely : queue - execution will wait for the running execution to complete

splitGenerator
JavascriptProcessor
Optional

When using Step.type "scripted-split-aggregate", defines how to generate the list to be operated on.

{
"splitGenerator": {
...
}
}
stepId
String
Required

Required Sets the id of the step.

Must be unique.

{
"stepId": "the-first-step-in-my-route"
}
timer
String
Optional

Depricated: use Trigger

Defines a timer to trigger the execution of a step.

There will likely only be one timer in a Workflow.

Accepts Apache Camel Timer query string parameters

{
"timer": "fixedRate=true&period=3600000"
}
trigger
Trigger
Optional

Defines how a workflow is started.

{
"trigger": {
...
}
}
type
String
Optional

Sets the type of the step.

Either "scripted", "scripted-split-aggregate", "scripted-auth" as "httpFile" as defined above.

Defaults to "scripted"

{
"type": "scripted-split-aggregate"
}
urlGenerator
JavascriptProcessor
Required

Required Defines how to generate the URL

This processor should not attempt to set the payload (the current internal logic may result in unexpected results). To set the payload, use the payloadGenerator

{
"urlGenerator": {
...
}
}

Timer

Defines a repeating, fixed-rate period trigger

JSON Properties

The following properties are available to set on the Timer JSON schema.

delay
Integer
Optional

Defines a delay in milliseconds before the first invocation.

Defaults to 0.

{
"delay": 60000
}
noTrace
Boolean
Optional

When true these executions will be omitted from tracing (monitoring)

period
Integer
Optional

Defines a delay in milliseconds between invocations.

Defaults to 1000.

{
"period": 60000
}

Trigger

Defines the starting condition for a workflow

JSON Properties

The following properties are available to set on the Trigger JSON schema.

fileWatcher
FileWatchingTrigger
Optional

Defines a trigger that fires when new lines are added to a file.

{
"fileWatcher": {
...
}
}
http
HttpRequestTrigger
Optional

Defines a trigger that fires when a matching http request is received.

{
"http": {
...
}
}
runOnce
Boolean
Optional

Sets trigger to run only once.

Defaults to false

{
"runOnce": true
}
runOnceNoTrace
Boolean
Optional

When true these executions will be omitted from tracing (monitoring)

timer
Timer
Optional

Defines a repeating period trigger

{
"timer": {
...
}
}

Workflow

Defines a set of Steps that the agent will perform in order to generate metrics

JSON Properties

The following properties are available to set on the Workflow JSON schema.

data
Object
Optional

A JSON Object for adding properties.

Used to pass parameters and data to the JavaScriptSource elements.

These properties will be merged with all other data fields in the json path, available to the step JavaScriptSource elements.

{
"data": {
"somedata" : {
"abc: 123
},
"someotherdata" : [ 1, 2, 3],
}
}
enabled
Boolean
Optional

Enable or disables the loading of the route.

Defaults to true

{
"enabled": false
}
name
String
Required

Required The user friendly name of the route.

{
"name": "my route"
}
steps
Step
Required

Required The list of Steps or actions to take to perform the intention of the Workflow.

Please note that steps are not executed in order, rather they are a group of actions that can send messages to one and other. The order of execution is defined by the actions taken by the Step

{
"steps": [
...
]
}

Workflow JS Contexts

These are the Javascript context objects in the Workflow package:

AuthenticationJavascriptContext

This is a specialised Javascript Context for authentication steps.

Most of the methods on Javascript Context are still available, the methods listed below are specialisations.

sendMetric and

Methods
GetAuthenticationPropertiesFromStep

String getAuthenticationPropertiesFromStep (String stepId, String key)

ACCESSES RESTRICTED DATA

Gets the authentication properties from another step. These properties can expire.

Returns
String

json string of authentication properties value or null if expired

Parameters
stepIdString

to fetch the property from

keyString

property to fetch

GetRestrictedDataFromHost

String getRestrictedDataFromHost (String host)

ACCESSES RESTRICTED DATA

Gets the json string of restricted data for a host name

hostData = JSON.parse(context.getRestrictedDataFromHost("myhost"));
Returns
String

json object string of host data

Parameters
hostString

to get the restricted data from

SetAuthenticationPropertiesOnStep

void setAuthenticationPropertiesOnStep (String stepName, Long expiresInMs, String key, String authenticationProperties)

ACCESSES RESTRICTED DATA

Sets the authentication properties from another step. These properties can expire.

Parameters
stepNameString

the name of the step to set properties on

expiresInMsLong

duration in milliseconds until the properties expire

keyString

property key to set

authenticationPropertiesString

json string of authentication properties to store

ByteBufferHandle

The ByteBufferHandle is a convenience "label" to make it clear that you're dealing with an internal byte buffer.

When you see a method taking or returning a ByteBufferHandle you know that you are dealing with a byte buffer.

See byte context

ByteContext

A low-level byte buffer manipulation interface providing minimal primitives for binary data operations.

Most operations either take or return a ByteBufferHandle. The byte buffer handle is a reference to a byte buffer in the agent - you will almost never interact with the buffer itself, rather you delegate the functionality to the agent.

The ByteContext offers the following categories of functionality:

  • conversion to and from text encoded bytes (base64, hex)
  • creating new byte arrays (create, createFromByteArray, createFromString)
  • byte array manipulation (concat, copy, getSize, resize, slice, release)
  • byte compression (gzip, gunzip, zip, unzip)
  • writing to byte buffer (writeByte, writeBytes)
  • reading from byte buffer (readByte, reader.available, reader.read, reader.readAll)

All high-level operations (multi-byte integers, strings, etc.) should be implemented in JavaScript using these primitives.

Methods

The following methods are available to call on the context.bytes() object.

Base64ToBinary

ByteBufferHandle base64ToBinary (String base64)

Converts a Base64 encoded String into a binary buffer.

Returns
ByteBufferHandle

A buffer containing the binary representation

Parameters
base64String

the Base64 encoded string to be converted

BinaryToBase64

String binaryToBase64 (ByteBufferHandle buffer)

Converts buffer contents to a Base64 encoded string.

Returns
String

the Base64 encoded string representation

Parameters
bufferByteBufferHandle

the binary buffer to convert

BinaryToHex

String binaryToHex (ByteBufferHandle buffer)

Converts buffer contents to a hexadecimal string representation.

let buffer = byteContext.createFrom([72, 101, 108, 108, 111]); // "Hello"
let hex = byteContext.binaryToHex(buffer);
console.log(hex); // "48656C6C6F"

// Useful for debugging or logging
function debugBuffer(buffer, label) {
console.log(label + ": " + byteContext.binaryToHex(buffer));
}

// Create checksums or hashes
function bufferFingerprint(buffer) {
return byteContext.binaryToHex(buffer).substring(0, 8);
}
Returns
String

Uppercase hexadecimal string representation

Parameters
bufferByteBufferHandle

The buffer to convert

Concat

ByteBufferHandle concat (ByteBufferHandle[] buffers)

Combines two buffers into a new buffer containing all bytes from both.

let header = byteContext.createFrom([0xFF, 0xFE]); // Magic bytes
let data = byteContext.createFrom([1, 2, 3, 4]); // Payload
let packet = byteContext.concat([header, data]);
// packet contains: [0xFF, 0xFE, 1, 2, 3, 4]
Returns
ByteBufferHandle

A new buffer containing concatenated data

Parameters
buffersByteBufferHandle[]

A list of buffers to concatenate

Copy

ByteBufferHandle copy (ByteBufferHandle sourceBuffer)

Creates a deep copy of an existing buffer.

let original = byteContext.create(10);
let copy = byteContext.copy(original);
// Modifying copy won't affect original
copy = byteContext.writeByte(copy, 0, 255);
console.log(byteContext.readByte(original, 0)); // 0 (unchanged)
Returns
ByteBufferHandle

A new buffer with identical contents

Parameters
sourceBufferByteBufferHandle

The buffer to copy

Create

ByteBufferHandle create (Integer size)

Creates a new buffer of the specified size, initialized with zeros.

let buffer = byteContext.create(1024);  // 1KB buffer of zeros
console.log(byteContext.getSize(buffer)); // 1024
Returns
ByteBufferHandle

A new buffer handle

Parameters
sizeInteger

The size of the buffer in bytes

CreateFromByteArray

ByteBufferHandle createFromByteArray (Byte[] bytes)

Creates a new buffer from a byte array.

// Create from existing data
let bytes = [0x48, 0x65, 0x6C, 0x6C, 0x6F]; // "Hello" in ASCII
let buffer = byteContext.createFrom(bytes);
console.log(byteContext.getSize(buffer)); // 5
Returns
ByteBufferHandle

A new buffer handle containing the byte data

Parameters
bytesByte[]

The byte array to copy from

CreateFromString

ByteBufferHandle createFromString (String string)

Creates a new buffer from a string.

// Create buffer from UTF-8 string
let text = "Hello, 世界!"; // Unicode text
let buffer = byteContext.createFrom(text);
Returns
ByteBufferHandle

A new buffer containing the UTF-8 encoded string data

Parameters
stringString

The string to convert to a buffer using UTF-8 encoding

GetSize

Integer getSize (ByteBufferHandle buffer)

Returns the current size of a buffer in bytes.

JavaScript Example:

let buffer = byteContext.create(42);
console.log(byteContext.getSize(buffer)); // 42

// Useful for iteration
for (let i = 0; i < byteContext.getSize(buffer); i++) {
console.log(byteContext.readByte(buffer, i));
}
Returns
Integer

The size in bytes

Parameters
bufferByteBufferHandle

The buffer to measure

Gunzip

ByteBufferHandle gunzip (ByteBufferHandle buffer)

Decompresses GZIP-compressed buffer contents.

let compressed = byteContext.gzip(originalBuffer);
let decompressed = byteContext.gunzip(compressed);

// Verify data integrity
function verifyCompression(original) {
let compressed = byteContext.gzip(original);
let restored = byteContext.gunzip(compressed);
return byteContext.binaryToHex(original) ===
byteContext.binaryToHex(restored);
}
Returns
ByteBufferHandle

A new buffer containing the decompressed data

Parameters
bufferByteBufferHandle

The GZIP-compressed buffer to decompress

Gzip

ByteBufferHandle gzip (ByteBufferHandle buffer)

Compresses buffer contents using GZIP compression.

let text = "This is a long string that will compress well when repeated. ";
let repeated = text.repeat(100); // Create redundant data
let textBuffer = createUTF8Buffer(repeated);
let compressed = byteContext.gzip(textBuffer);

console.log("Original:", byteContext.getSize(textBuffer));
console.log("Compressed:", byteContext.getSize(compressed));
// Compressed should be much smaller
Returns
ByteBufferHandle

A new buffer containing GZIP-compressed data

Parameters
bufferByteBufferHandle

The buffer to compress

HexToBinary

ByteBufferHandle hexToBinary (String hex)

Converts a hexadecimal string to binary buffer data.

let buffer = byteContext.hexToBinary("48656C6C6F"); // "Hello" in hex
console.log(byteContext.getSize(buffer)); // 5
console.log(byteContext.readByte(buffer, 0)); // 72 (0x48)

// Parse hex data from configuration or network
let magicBytes = byteContext.hexToBinary("DEADBEEF");
let packet = byteContext.concat(magicBytes, payload);
Returns
ByteBufferHandle

A buffer containing the binary representation

Parameters
hexString

Hexadecimal string (case-insensitive, no 0x prefix)

ReadByte

Integer readByte (ByteBufferHandle fromBuffer, Integer offset)

Reads a single byte from the buffer at the specified offset.

let buffer = byteContext.create(5);
buffer = byteContext.writeByte(buffer, 2, 170); // 0xAA
let value = byteContext.readByte(buffer, 2);
console.log(value); // 170

// Read a 32-bit big-endian integer
function readInt32BE(buffer, offset) {
return (byteContext.readByte(buffer, offset) << 24) |
(byteContext.readByte(buffer, offset + 1) << 16) |
(byteContext.readByte(buffer, offset + 2) << 8) |
byteContext.readByte(buffer, offset + 3);
}
Returns
Integer

The byte value (0-255)

Parameters
fromBufferByteBufferHandle

The buffer to read from

offsetInteger

The position to read from (0-based)

Reader

ByteReader reader (ByteBufferHandle buffer)

Creates a sequential reader for efficient forward-only reading of buffer data. This is more efficient than random access for sequential operations.

let buffer = createNetworkPacket();
let reader = byteContext.reader(buffer);

// Read packet header
let version = reader.readByte();
let flags = reader.readByte();
let length = reader.readInt32BE();

// Read payload
let payload = reader.readBytes(length);

// Reader automatically tracks position, more efficient than manual offset tracking
Returns
ByteReader

A ByteReader instance for sequential reading

Parameters
bufferByteBufferHandle

The buffer to create a reader for

Reader

ByteReader reader ()

Reads from the context stream

Returns
ByteReader

A ByteReader from the context input stream

Release

void release (ByteBufferHandle[] buffers)

Securely releases buffers from memory.

Parameters
buffersByteBufferHandle[]

The buffers to release

Resize

ByteBufferHandle resize (ByteBufferHandle buffer, Integer newSize)

Changes the size of a buffer. If enlarged, new bytes are zero-filled. If shrunk, excess bytes are discarded.

let buffer = byteContext.create(10);
buffer = byteContext.resize(buffer, 20); // Grow to 20 bytes (zeros added)
buffer = byteContext.resize(buffer, 5); // Shrink to 5 bytes

// Implementing append by resizing
function appendByte(buffer, value) {
let size = byteContext.getSize(buffer);
buffer = byteContext.resize(buffer, size + 1);
return byteContext.writeByte(buffer, size, value);
}
Returns
ByteBufferHandle

The resized buffer identifier

Parameters
bufferByteBufferHandle

The buffer to resize

newSizeInteger

The new size in bytes

Slice

ByteBufferHandle slice (ByteBufferHandle sourceBuffer, Integer offset, Integer length)

Extracts a portion of a buffer without modifying the original.

let buffer = byteContext.create(100);
let middle = byteContext.slice(buffer, 25, 50); // Extract bytes 25-74
console.log(byteContext.getSize(middle)); // 50

// Extract from offset to end
let tail = byteContext.slice(buffer, 80, byteContext.getSize(buffer) - 80);
Returns
ByteBufferHandle

A new buffer containing the extracted bytes

Parameters
sourceBufferByteBufferHandle

The buffer to extract from

offsetInteger

The starting position (0-based)

lengthInteger

The number of bytes to extract

Unzip

ByteBufferHandle unzip (ByteBufferHandle buffer)

Decompresses ZIP-compressed buffer contents.

let compressed = byteContext.zip(originalBuffer);
let decompressed = byteContext.unzip(compressed);

// Handle multiple compression formats
function smartDecompress(buffer) {
try {
return byteContext.gunzip(buffer); // Try GZIP first
} catch (e) {
return byteContext.unzip(buffer); // Fall back to ZIP
}
}
Returns
ByteBufferHandle

A new buffer containing the decompressed data

Parameters
bufferByteBufferHandle

The ZIP-compressed buffer to decompress

WriteByte

void writeByte (ByteBufferHandle buffer, Integer offset, Integer value)

Writes a single byte to the buffer at the specified offset.

let buffer = byteContext.create(10);
buffer = byteContext.writeByte(buffer, 0, 0xFF); // Write 255
buffer = byteContext.writeByte(buffer, 1, 0x00); // Write 0

// Build a 32-bit big-endian integer
function writeInt32BE(buffer, offset, value) {
buffer = byteContext.writeByte(buffer, offset, (value >>> 24) & 0xFF);
buffer = byteContext.writeByte(buffer, offset + 1, (value >>> 16) & 0xFF);
buffer = byteContext.writeByte(buffer, offset + 2, (value >>> 8) & 0xFF);
buffer = byteContext.writeByte(buffer, offset + 3, value & 0xFF);
return buffer;
}
Parameters
bufferByteBufferHandle

The buffer to write to

offsetInteger

The position to write at (0-based)

valueInteger

The byte value (0-255, will be masked to 8 bits)

WriteBytes

void writeBytes (ByteBufferHandle toBuffer, Integer offset, ByteBufferHandle sourceBuffer, Integer sourceOffset, Integer length)

Copies bytes from one buffer to another. This is the most efficient way to move large amounts of data between buffers.

let source = byteContext.createFrom([1, 2, 3, 4, 5]);
let dest = byteContext.create(10);

// Copy bytes 1-3 from source to position 2 in dest
byteContext.writeBytes(dest, 2, source, 1, 3);
// dest now contains: [0, 0, 2, 3, 4, 0, 0, 0, 0, 0]
Parameters
toBufferByteBufferHandle

The destination buffer

offsetInteger

The position in the destination to start writing

sourceBufferByteBufferHandle

The source buffer to copy from

sourceOffsetInteger

The position in the source to start reading

lengthInteger

The number of bytes to copy

Zip

ByteBufferHandle zip (ByteBufferHandle buffer)

Compresses buffer contents using ZIP compression.

let documentBuffer = createDocumentBuffer();
let zipped = byteContext.zip(documentBuffer);

// ZIP provides better compression ratios for some data types
let gzipSize = byteContext.getSize(byteContext.gzip(documentBuffer));
let zipSize = byteContext.getSize(zipped);
console.log("GZIP vs ZIP size:", gzipSize, "vs", zipSize);
Returns
ByteBufferHandle

A new buffer containing ZIP-compressed data

Parameters
bufferByteBufferHandle

The buffer to compress

ByteReader

A sequential reader for efficient forward-only reading of buffer data.

Methods

The following methods are available to call on the context.bytes().reader(...) object.

Available

Integer available ()

Returns the number of bytes that can be read from the current position.

Returns
Integer

the number of available bytes.

Read

ByteBufferHandle read (Integer length)

Reads the specified number of bytes from the current position into a new buffer.

Returns
ByteBufferHandle

Buffer handle for the buffer containing the read bytes

Parameters
lengthInteger

Number of bytes to read

ReadAll

ByteBufferHandle readAll ()

Reads all the available bytes from the current position into a new buffer.

Returns
ByteBufferHandle

Buffer handle for the buffer containing the read bytes

CryptoContext

The Crypto context provides cryptographic operations for signing, encryption and random byte generation.

It works with the byte context, and all parameters and returns are byte buffer handles.

The opscotch cryptography functions use the libsodium implementation, which is a high-grade industry standard.

Some notes about keys:

  • Keys need to be a specific kind and size for each function and must be registered (either in the bootstrap or during a workflow) before used - see registerKey.
  • You can generate a key for a specific function using generateKeyPair
  • You can validate a key for a given function using validateKey
  • For key requirements see Key

The following cryptographic functions are provided for use within workflows:

  • Public key signatures
    • Used to create and verify digital signatures that ensure message authenticity and integrity. A private key is used to generate a unique signature for a message, while the corresponding public key allows anyone to verify the signature. A verified signature proves it was created by the owner of the private key, and the message hasn't been tampered with.
    • methods:
      • sign
      • verifySignature
    • Algorithm used: Ed25519
    • You can provide your own Ed25519 keys
  • Authenticated public key encryption
    • Used to encrypt messages that can only be decrypted by a specific intended recipient and authenticates the sender's identity. The recipient can verify the message came from the claimed sender, while ensuring message confidentiality. This provides both encryption and authentication in a single operation.
    • methods:
      • encryptPublicKey
      • decryptPublicKey
    • Algorithms used:
      • Key exchange: X25519
      • Encryption: XSalsa20
      • Authentication: Poly1305
    • You can provide your own X25519 keys
  • Anonymous public key encryption
    • Used for one-way encryption where only the recipient can decrypt the message using their private key. The sender remains anonymous as no authentication is performed. This provides message confidentiality without revealing the sender's identity.
    • methods:
      • encryptAnonymous
      • decryptAnonymous
    • Algorithms used:
      • Key exchange: X25519
      • Encryption: XSalsa20 stream cipher
    • You can provide your own X25519 keys
  • Symmetric secret key encryption
    • Used when both parties share a single secret key that is used for both encryption and decryption. The same key must be securely shared between parties beforehand. This provides fast and secure encryption for parties who have already established a shared secret key.
    • methods:
      • encryptSymmetric
      • decryptSymmetric
    • Algorithm used: XSalsa20 stream cipher
    • You can provide your own 32-byte secret key
  • Random byte generation
    • Generate cryptographically random byte array
    • methods:
      • randomBytes
  • Hahsing
    • Generate cryptographically secure hash values
    • methods:
      • hash
  • Key management
    • Various functions for working with keys:
    • methods:
      • generateKeyPair
      • registerKey
      • validateKey
Methods

The following methods are available to call on the context.crypto() object.

DecryptAnonymous

ByteBufferHandle decryptAnonymous (ByteBufferHandle payloadBytes, String registeredPublicKeyId, String registeredPrivateKeyId)

Decrypts a payload using anonymous public-key encryption.

Returns
ByteBufferHandle

The byte buffer handle for the decrypted data

Parameters
payloadBytesByteBufferHandle

The byte buffer handle for payload bytes to decrypt

registeredPublicKeyIdString

The registered key id of the recipient public key used for decryption. (For key requirements see Key)

registeredPrivateKeyIdString

The registered key id of the recipient secret key used for decryption. (For key requirements see Key)

DecryptPublicKey

ByteBufferHandle decryptPublicKey (ByteBufferHandle payloadBytes, ByteBufferHandle nonceBytes, String registeredPublicKeyId, String registeredPrivateKeyId)

Decrypts a payload using authenticated public-key encryption.

Returns
ByteBufferHandle

The byte buffer handle for the decrypted data

Parameters
payloadBytesByteBufferHandle

The byte buffer handle for payload bytes to decrypt

nonceBytesByteBufferHandle

The byte buffer handle for the unique 24-byte nonce for this encryption

registeredPublicKeyIdString

The registered key id of the sender public key used for decryption. (For key requirements see Key)

registeredPrivateKeyIdString

The registered key id of the recipient public key used for decryption. (For key requirements see Key)

DecryptSymmetric

ByteBufferHandle decryptSymmetric (ByteBufferHandle encryptedBytes, ByteBufferHandle nonceBytes, String registeredSharedKeyId)

Decrypts a payload using symmetric decryption.

Returns
ByteBufferHandle

The byte buffer handle for decrypted data

Parameters
encryptedBytesByteBufferHandle

The byte buffer handle for encrypted bytes to decrypt

nonceBytesByteBufferHandle

The byte buffer handle for the 24-byte nonce used during encryption

registeredSharedKeyIdString

The registered key id for the secret key used for decryption (same as used for encryption). (For key requirements see Key)

EncryptAnonymous

ByteBufferHandle encryptAnonymous (ByteBufferHandle payloadBytes, String registeredPublicKeyId)

Encrypts a payload using anonymous public-key encryption.

This will be used when the sender uses the recipient public key to encrypt and the payload is only openable by the holder of the secret key. There is no sender identity or verification.

Returns
ByteBufferHandle

The byte buffer handle for the encrypted data

Parameters
payloadBytesByteBufferHandle

The byte buffer handle for payload bytes to decrypt

registeredPublicKeyIdString

The registered key id of the recipient public key used for decryption. (For key requirements see Key)

EncryptPublicKey

ByteBufferHandle encryptPublicKey (ByteBufferHandle payloadBytes, ByteBufferHandle nonceBytes, String registeredPublicKeyId, String registeredPrivateKeyId)

Encrypts a payload using authenticated public-key encryption. This is used when the recipient knows the sender and vice versa. The payload will only be openable by the intended recipient and will only be openable if verified from the sender.

Returns
ByteBufferHandle

The byte buffer handle for encrypted data

Parameters
payloadBytesByteBufferHandle

The byte buffer handle for payload bytes to encrypt

nonceBytesByteBufferHandle

The byte buffer handle for the unique 24-byte nonce for this encryption

registeredPublicKeyIdString

The registered key id of the recipient public key used for encryption. (For key requirements see Key)

registeredPrivateKeyIdString

The registered key id of a sender secret key used for encryption. (For key requirements see Key)

EncryptSymmetric

ByteBufferHandle encryptSymmetric (ByteBufferHandle payloadBytes, ByteBufferHandle nonceBytes, String registeredSharedKeyId)

Encrypts a payload using symmetric encryption.

Returns
ByteBufferHandle

The byte buffer handle for encrypted data as a String

Parameters
payloadBytesByteBufferHandle

The byte buffer handle for payload bytes to encrypt

nonceBytesByteBufferHandle

The byte buffer handle for the unique 24-byte nonce for this encryption

registeredSharedKeyIdString

The registered key id for the shared secret key used for encryption. (For key requirements see Key)

GenerateKeyPair

ByteBufferHandle[] generateKeyPair (String purpose)

Generate a new public/private key pair for the given type

Returns
ByteBufferHandle[]

a pair of keys, index 0 is the public key, index 1 is the secret key

Parameters
purposeString

the purpose of key to generate (sign, box, secretbox)

Hash

ByteBufferHandle hash (ByteBufferHandle input)

Generates a consistent hash for the same input

Returns
ByteBufferHandle

The byte buffer handle for the hashed value

Parameters
inputByteBufferHandle

The byte buffer handle for input to hash

RandomBytes

ByteBufferHandle randomBytes (Integer length)

Generates random bytes that are cryptographically secure.

Returns
ByteBufferHandle

The byte buffer handle for generated random bytes as a String

Parameters
lengthInteger

The number of random bytes to generate

RegisterKey

String registerKey (String purpose, String type, String keyHex)

Registers a cryptographic key and returns a registered key id for use in the current context

Public and secret keys need to be registered separately.

The purpose is important and can be one of the following cryptographic primitives:

  • sign - used for sign and verifySignature using public/secret keys
  • authenticated - used for encryptPublicKey and decryptPublicKey for mutually authenticated public-key encryption
  • symmetric - used for encryptSymmetric and decryptSymmetric - this only uses a secret key
  • anonymous - used for encryptAnonymous and decryptAnonymous - this is the classic public/private key encryption

The type will either be public or secret depending on the key being registered.

Each permutation of purpose and type will have a specific required key length in bytes and an error will be thrown if the byte length (not the hex character length) does not match.

const keyId = context.crypto().registerKey("sign", "secret", "6250E4....0E4");
Returns
String

the registered key id

Parameters
purposeString

one of: sign, authenticated, symmetric, anonymous

typeString

one of public or secret

keyHexString

string representation of the key bytes in hex format

Sign

ByteBufferHandle sign (ByteBufferHandle payloadBytes, String registeredKeyId)

Signs a payload using a secret key and returns the signature.

Returns
ByteBufferHandle

The byte buffer handle for signature as a String

Parameters
payloadBytesByteBufferHandle

The byte buffer handle for payload bytes to sign

registeredKeyIdString

The key id for the secret key bytes used for signing. (For key requirements see Key)

ValidateKey

Boolean validateKey (String id, String purpose, String type)

Determines if a given key id matches a registered key with the given purpose and type

Returns
Boolean

true if the key is found and matches the criteria, otherwise false

Parameters
idString

of the key to find

purposeString

intended purpose of the key

typeString

intended type of the key

VerifySignature

Boolean verifySignature (ByteBufferHandle signatureBytes, ByteBufferHandle messageBytes, String registeredPublicKeyId)

Verifies that a signature matches a message using a public key.

Returns
Boolean

true if the signature is valid, false otherwise

Parameters
signatureBytesByteBufferHandle

The byte buffer handle for signature bytes to verify

messageBytesByteBufferHandle

The byte buffer handle for message bytes that was signed

registeredPublicKeyIdString

The registered key id for the public key bytes to verify against. (For key requirements see Key)

DiagnosticsContext

An interface for interacting with OpenTelemetry

Methods

The following methods are available to call on the context.diagnostic() object.

Errored

void errored (String error)

Mark the trace as errored and records the error message

Parameters
errorString

to add to trace

Errored

void errored (String type, String error)

Mark the trace as errored and records the error type and message

Parameters
typeString

string type that will be set on the trace

errorString

to add to the trace

Event

void event (String event)

Add an event to a trace

Parameters
eventString

to add to trace.

SetAttribute

void setAttribute (String key, String value)

Set an attribute onto the trace

Parameters
keyString

of the attribute

valueString

of the attribute

SetAttribute

void setAttribute (String key, Integer value)

Set an attribute onto the trace

Parameters
keyString

of the attribute

valueInteger

of the attribute

SetAttribute

void setAttribute (String key, Double value)

Set an attribute onto the trace

Parameters
keyString

of the attribute

valueDouble

of the attribute

FilesContext

The FileContext provides workflow access to files.

Only files defined in the bootstrap allowFileAccess property can be accessed.

Methods

The following methods are available to call on the context.files(fileId) object.

Copy

void copy (String srcPath, String dstFileId, String dstPath, Boolean mkdir, Boolean overwrite)

Copies a file from one location to another

Parameters
srcPathString

relative to this bootstrap FilePermitter path context

dstFileIdString

the FilePermitter id for the copy destination

dstPathString

relative to this bootstrap FilePermitter path context

mkdirBoolean

true to make destination directories

overwriteBoolean

true to allow overwriting existing files

Delete

void delete (String file)

Delete a file

Parameters
fileString

to be deleted

List

String list (String path)

Lists the directory

Returns
String

A JSON array as a string of { "name" : "...", "type" : ("FILE"|"DIRECTORY"), "bytes" : 0, "modified" : 0 }

Parameters
pathString

relative to the bootstrap FilePermitter path

Move

void move (String srcPath, String dstFileId, String dstPath, Boolean mkdir, Boolean overwrite)

Moves a file from one location to another

Parameters
srcPathString

relative to this bootstrap FilePermitter path context

dstFileIdString

the FilePermitter id for the move destination

dstPathString

relative to this bootstrap FilePermitter path context

mkdirBoolean

true to make destination directories

overwriteBoolean

true to allow overwriting existing files

Read

String read (String file)

Read the contents of the file as a string

Returns
String

string contents of file

Parameters
fileString

relative to the bootstrap FilePermitter path

Reader

ByteReader reader (String file)

Creates a byte reader on the contents of the file

Returns
ByteReader

byte reader for contents of file

Parameters
fileString

relative to the bootstrap FilePermitter path

Write

void write (String file, String body)

Write the string contents to a file

Parameters
fileString

relative to the bootstrap FilePermitter path

bodyString

as a string

WriteBinary

void writeBinary (String file, ByteBufferHandle buffer, Long offSet)

Write the binary contents from the byte buffer to a file

Parameters
fileString

relative to the bootstrap FilePermitter path

bufferByteBufferHandle

byte handle of the buffer to read from

offSetLong

to start writing

JavascriptContext

This is the entry point to the agent functionality from javascript.

Methods

The following methods are available to call on the context object.

AddSplitReturnItem

void addSplitReturnItem (String item)

When the current step is a "scripted-split-aggregate" type (see Step the processed item must be added to the aggregate using this method.

context.addSplitReturnItem("hello world");
Parameters
itemString
AddSystemError

void addSystemError (String error)

Adds an error not intended for a user outside the agent. It will also mark the context as in an error state.

System errors would generally be thrown or handled.

Parameters
errorString

System error

AddUserError

void addUserError (String error)

Adds an error intended for a user outside the agent. It will also mark the context as in an error state.

User errors would generally make their way to a human.

Parameters
errorString

User error

Bytes

ByteContext bytes ()

Obtain a Byte context for working with bytes

Counter

Double counter (String name, Double add)

Atomically add to or update a thread safe atomic counter and return the updated value

To just get the value pass 0 for add

Returns
Double

the updated value

Parameters
nameString

of the counter to add or update

addDouble

the value to add to the counter - it can be negative or 0 if you want to get the value

Crypto

CryptoContext crypto ()

Obtain a Cryptography context for working with cryptography

Delta

Double delta (String key, Double currentValue)

Returns the differences between the current value and the last value stored for given key

delta = context.delta("myTs", 12);
Returns
Double

currentValue - lastValue

Parameters
keyString

to lookup in persistence

currentValueDouble

the current value to compare to the last value stored

Diagnostic

DiagnosticsContext diagnostic ()

Obtain a Trace context for adding data to sent traces

DiagnosticLog

void diagnosticLog (String message)

Write a diagnostic log. This will only be emitted in development mode, or in Production mode if the step is enabled via a "enableDiagnostics" message

context.diagnosticLog("Hello World");
Parameters
messageString

to log

End

void end ()

Termaintes the running flow

context.end();
Files

FilesContext files (String id)

Request access to the bootstrap file permission

@param id in bootstrap for the file permission @return FilesContext

Parameters
idString
GetBody

String getBody ()

A shorthand for: check getMessageBodyAsString()then check getPassedMessageAsString()

body = context.getBody();

@return the contents eiter passed into the step or set by the step.

GetData

String getData ()

data = JSON.parse(context.getData());
Returns
String

the JSON string for the data for this step

GetData

String getData (String key)

data = context.getData(key);
Returns
String

the string for the key in the data for this step

Parameters
keyString
GetHeader

String getHeader (String name)

Get a header from the previous request/response

headerArray = context.getHeader("aHeader");
header = headerArray[0];
Returns
String

the header value as a json array, or an empty array

Parameters
nameString
GetMessageBodyAsString

String getMessageBodyAsString ()

Get the current message body, this could be the response from an http call for example

body = context.getMessageBodyAsString();
Returns
String

the current message body

GetPassedMessageAsString

String getPassedMessageAsString ()

Get the message body that was passed to this step.

passedMessage = context.getPassedMessageAsString();
Returns
String

the message body

GetPersistedItem

String getPersistedItem (String key)

Gets an item from the step persistence

item = context.getPersistedItem("myItem");
Returns
String

the string value

Parameters
keyString
GetProperty

Object getProperty (String key)

Gets a property from this running context

property = context.getProperty("aKey");
Returns
Object

the propery for the key

Parameters
keyString

of the property to get

GetStepProperties

Object getStepProperties ()

Returns the set properties for the Step. These properties will persist after requests but not over config reloads/restarts

property = context.getStepProperties().put("myProperty", "ok");
Returns
Object

the propery object

GetStream

ByteReader getStream ()

Get the stream on the context.

Returns
ByteReader

a byte reader of the stream

GetTimestamp

Long getTimestamp ()

Get the current timestamp (note that the timestamp might be set by a test or other mechanism)

ts = context.getTimestamp();

date = new Date(context.getTimestamp())
Returns
Long

the current timestamp

GetTimestampManager

TimestampManager getTimestampManager ()

The timestamp manager allows for persistence of timestamps

tm = context.getTimestampManager();
Returns
TimestampManager

the TimestampManager for the step

Hash

String hash (String toHash)

When hashing a value, the original and the hash are emitted to the log to be referred to at a later date. The hash can be used in metrics etc so that the original value is not transmitted

hashedValue = context.hash("hello world");
Returns
String

the hashed value

Parameters
toHashString
JsonPath

String jsonPath (String json, String expression)

Returns the result from a JSONPath expression

Returns
String

json string

Parameters
jsonString
expressionString
MergeJsonStrings

String mergeJsonStrings (String one, String two)

Returns a merged json string

Returns
String

the merged json object

Parameters
oneString
twoString
Queue

PersistentQueueContext queue ()

Returns the high performance persistent queue

RegexMatch

String regexMatch (String regex, String input)

Returns the regex matches

Returns
String

array of matches

Parameters
regexString
inputString
RemoveHeader

void removeHeader (String name)

Remove a header from the current state

context.removeHeader("aHeader");
Parameters
nameString
SendMetric

void sendMetric (String key, Double value)

Send a metric

context.sendMetric("theKey", 123);
Parameters
keyString

of the metric

valueDouble

of the metric

SendMetric

void sendMetric (String routingToken, Long timestamp, String key, Double value, String metadata)

Send a metric

context.sendMetric("theRoutingToken", theTimestamp, "theKey", 123, { "someMeta" : "Data"});
Parameters
routingTokenString

the routing token for the metric

timestampLong

the timestamp of the metric

keyString

the key/name of the metric

valueDouble

the numeric value of the metric

metadataString

additional metadata for the metric as key-value pairs

SendMetric

void sendMetric (Long timestamp, String key, Double value)

Send a metric

context.sendMetric(theTimestamp, "theKey", 123);
Parameters
timestampLong

the timestamp of the metric

keyString

the key/name of the metric

valueDouble

the numeric value of the metric

SendMetric

void sendMetric (Long timestamp, String key, Double value, String metadata)

Send a metric

context.sendMetric(theTimestamp, "theKey", 123, { "someMeta" : "Data"});
Parameters
timestampLong

the timestamp of the metric

keyString

the key/name of the metric

valueDouble

the numeric value of the metric

metadataString

additional metadata for the metric as key-value pairs

SendToStep

JavascriptStateContext sendToStep (String stepName, String body)

Send a message to another step and return a completed context upon completion

var completedContext = context.sendToStep("myStep", "theBody");
Returns
JavascriptStateContext

the completed context.

Parameters
stepNameString

to send to

bodyString

to send

SendToStep

JavascriptStateContext sendToStep (String stepName, String body, String headers)

Send a message to another step with headers (key pair available from context.getHeader(...) and return a completed context upon completion

var completedContext = context.sendToStep("myStep", "theBody", { "header1" : "abc"});
Returns
JavascriptStateContext

the completed context.

Parameters
stepNameString

to send to

bodyString

to send

headersString

to send

SendToStepAndForget

void sendToStepAndForget (String stepName, String body)

Send a message to another step and returns immediately. The step called will be processed in another thread, and you will access to the result.

context.sendToStep("myStep", "theBody");
Parameters
stepNameString

to send to

bodyString

to send

SendToStepAndForget

void sendToStepAndForget (String stepName, String body, String headers)

Send a message to another step with headers (key pair available from context.getHeader(...) and returns immediately

context.sendToStep("myStep", "theBody", { "header1" : "abc"});
Parameters
stepNameString

to send to

bodyString

to send

headersString

to send

SetBody

void setBody (Object body)

An alias for setMessage(...)

context.setBody("hello");
Parameters
bodyObject

to set

SetCounter

void setCounter (String name, Double value)

Atomically set the counter to an absolute value

Parameters
nameString

of the counter to add or update

valueDouble

to set the counter to

SetData

void setData (String data)

Set the JSON data for this step

context.setData(JSON.stringify(data));
Parameters
dataString
SetHeader

void setHeader (String name, Object value)

Add a header to the next http request

context.setHeader("aHeader", "aValue");
Parameters
nameString
valueObject
SetHttpMethod

void setHttpMethod (String method)

Set the HTTP method for the next http action

This is generally used when a method other than the default is required.

The HTTP method will default to GET unless there is a payload body then it will default to POST

context.setHttpMethod("POST");
Parameters
methodString
SetMessage

void setMessage (Object message)

Sets the message body for this running exchange

context.setMessage("hello world");
Parameters
messageObject
SetPersistedItem

void setPersistedItem (String key, String value)

Sets an item to the step persistence

context.setPersistedItem("myItem", "theValue");
Parameters
keyString
valueString
SetProperty

void setProperty (String key, Object value)

Sets a property onto this running context to be available in downstream step execution

This differs from setPersistedItem in that setPersistedItem sets onto the STEP to be available on THIS STEP in future runs, while setProperty makes an item available to OTHER steps

context.setProperty("aKey", "aValue");
Parameters
keyString

of the property to set

valueObject

of the property to set

SetStream

void setStream (ByteReader reader)

Sets the body content from the provided byte buffer.

context.setStream(buffer);

@param reader name containing the body content to be set

Parameters
readerByteReader
SetStreamFromString

void setStreamFromString (String streamString)

Sets a stream from a string

Parameters
streamStringString

to set as a stream

SetUrl

void setUrl (String hostref, String path)

Set the url for the next http action with reference to a named host

context.setUrl("myHost", "/a/path");
Parameters
hostrefString
pathString
Sleep

void sleep (Long ms)

Force the currently running script to sleep for the given milliseconds

context.sleep(100);
Parameters
msLong
XmlToJson

String xmlToJson (String xml)

Returns a json string from an xml string

Returns
String

json string

Parameters
xmlString

JavascriptStateContext

The Javascript State Context is a reduced version of the JavascriptContext containing readonly functions.

This context is returned from context.sendToStep(..) and contains the completed context of the step that was sent to.

Methods

The following methods are available to call on the var returnedContext = context.sendToStep(...) object.

GetAllErrors

String getAllErrors ()

Retrieves a list of all error messages associated with the current context.

Returns
String

a list of error messages, or an empty list if no errors are present.

GetBody

String getBody ()

A shorthand for: check getMessageBodyAsString()then check getPassedMessageAsString()

body = context.getBody();

@return the contents eiter passed into the step or set by the step.

GetFirstError

String getFirstError (String errors)

Retrieves the first error message from a given list of errors, if available.

Returns
String

the first error message if the list is not empty, or null if the list is empty or null

Parameters
errorsString

the list of error messages to retrieve the first error from

GetMessageBodyAsString

String getMessageBodyAsString ()

Get the current message body, this could be the response from an http call for example

body = context.getMessageBodyAsString();
Returns
String

the current message body

GetProperty

Object getProperty (String key)

Gets a property from this running context

property = context.getProperty("aKey");
Returns
Object

the propery for the key

Parameters
keyString

of the property to get

GetStepProperties

Object getStepProperties ()

Returns the set properties for the Step. These properties will persist after requests but not over config reloads/restarts

property = context.getStepProperties().put("myProperty", "ok");
Returns
Object

the propery object

GetSystemErrors

String getSystemErrors ()

Retrieves a list of system-specific error messages associated with the current context.

Returns
String

a list of system error messages, or an empty list if no system errors are present.

GetUserErrors

String getUserErrors ()

Retrieves a list of user-specific error messages associated with the current context.

Returns
String

a list of user error messages, or an empty list if no user errors are present.

HasSystemErrors

Boolean hasSystemErrors ()

Checks if there are any system-specific errors in the current context.

Returns
Boolean

true if system errors are present, false otherwise.

HasUserErrors

Boolean hasUserErrors ()

Checks if there are any user-specific errors in the current context.

Returns
Boolean

true if user errors are present, false otherwise.

IsErrored

Boolean isErrored ()

Indicates whether the current context is in an errored state.

Returns
Boolean

true if the context has encountered errors, false otherwise.

PersistentQueueContext

A high performance implementation of persistent FIFO queue.

The persistence context is got via context.queue().

Once the queue is obtained, items can be added and removed over multiple runs.

The queue will store a small amount of items in memory and overflow to disk.

Queue items will persist over agent restarts.

Methods
Push

void push (String item)

Add an item to the end of the persistent queue.

context.queue().push("adding item");
Parameters
itemString
PushArray

void pushArray (java.util.Collection<String> array)

Add the contents of an array of item to the end of the persistent queue.

context.queue().pushArray(["adding", "multiple", "items"]);
Parameters
arrayjava.util.Collection<String>
ReturnArray

void returnArray (java.util.Collection<String> array)

Return the array items to the head of the queue

Parameters
arrayjava.util.Collection<String>

of items to add

ReturnItem

void returnItem (String item)

Return the item to the head of the queue

Parameters
itemString

to return

Take

String take (Integer count)

Request the given amount of items from the queue or an empty array when no items available.

NOTE: the returned amount may not be the entire available items. The method should be called repeatedly until the desired amount is collected. This function waits for a short period for data to be loaded from file and may not load all the data.

var items = context.queue().take(1000);
Parameters
countInteger

TimestampManager

Looks after timestamps for metrics, for example recording the last known timestamp for a metric

TimestampManager is local to the step.

Timestamps can have a named key, or if not provided with a key, will just store with a default key.

Methods
FirstTimestamp

Long firstTimestamp ()

Returns
Long

the earliest timestamp stored

Get

Long get ()

Returns
Long

the last timestamp set without a key

Get

Long get (String key)

Returns
Long

the last timestamp set for the given key

Parameters
keyString
MinutesAgo

Integer minutesAgo (Long timestamp)

Returns
Integer

the number of minutes since the given timestamp

Parameters
timestampLong
Set

void set (String timestamp)

Sets the timestamp without a key see: set(String key, String timestamp)

Parameters
timestampString
Set

void set (String key, String timestamp)

Sets the timestamp for the given key

Parameters
keyString
timestampString
SetIfLastest

void setIfLastest (String key, String timestamp)

Only performs the set operation if the passed timestamp is later than the previously stored.

Parameters
keyString
timestampString

opscotch testing model

The opscotch testing model describes how to define tests that are executed against a running opscotch agent.

The test runner configuration is passed to the test runner and describes the locations of tests and resource files. The test configuration describes each individual test.

Here is the outline of the entire structure of the opscotch testing models: the runner configuration and the test configuration.

Note that not every field is required, so be sure to check the detailed descriptions.

The test runner schema overview

{
"resourceDir": "",
"resourceDirs": [
""
],
"testDir": "",
"testDirs": [
""
],
"license": ""
}

The test schema

{
"ignore": true,
"fromDirectory": "",
"testThisStep": "",
"useThisTestConfigFile": "",
"useThisTestBootstrapFile": "",
"mockEndpointResponses" : [
{
"whenThisIsCalled": "",
"expectedPayload": "",
"expectedHeaders": {
"": [""]
},
"returnThisFile": "",
"returnThisStatusCode" : 0,
"mockedHeaders" : {
"": [""]
},
"thisManyTimes" : 0
}
],
"theseMetricsShouldHaveBeenSent" : [
{
"timestamp": 0,
"key": "",
"value": 0.0,
"dimensionMap" : {
"": ""
}
}
],
"theseLogsShouldHaveBeenSent" : [
""
],
"logsShouldNotContain" : [
""
],
"makeTheseCalls" : [
{
"url": "",
"expectedResponse": "",
"expectedSize": 0,
"method": "",
"headers": [
[ "" , "" ]
],
"body": "",
"timeoutSeconds" : 0
}
],
"timestampOverride": 0,
"secondsToWaitForCompletion" : 0
}

Test JSON Schemas

JSON Schema in the Package:

HttpCall

Make an http call and assert results

JSON Properties

The following properties are available to set on the HttpCall JSON schema.

body
String
Optional

The http body to send

expectedResponse
String
Optional

The expected response

expectedResponseCode
Integer
Optional

The expected HTTP response code from the request.

This property is optional and defaults to 200, which usually indicates a successful HTTP response.

expectedSize
Integer
Optional

The expected size of the response

headers
String[]
Optional

The http headers to use

method
String
Optional

The http method to use

Defaults to 'get'

timeoutSeconds
Integer
Optional

The allowed timeout of the http call in seconds

Defaults to 10

url
String
Optional

The url to call

MockHttpResponse

Instructs the mock http server what urls to expect and how to respond.

These requests and responses are required to have been called by the test, otherwise the test will fail.

JSON Properties

The following properties are available to set on the MockHttpResponse JSON schema.

delay
Integer
Optional

The number of milliseconds to delay the response This will default to 0

{
"delay" : 0
}
expectedHeaders
String>
Optional

If set, will assert that expectedHeader's key/value pair is found within the HTTP header. As headers can have multiple values the value is represented as an array.

{
"expectedHeaders" : {"some": ["thing"] }
}
expectedPayload
String
Optional

If set will assert that the exact payload was received.

{
"expectedPayload": "{\"some\":\"thing\"}"
}
mockedHeaders
String>
Optional

If set will return these headers with the response. As headers can have multiple values the value is represented as an array.

{
"mockedHeaders" : {
"Set-Cookie": ["JSESSIONID=A","X-CSRF-TOKEN=B"]
}
}
returnThisFile
String
Optional

The file path of the response to return.

{
"returnThisFile" : "test.response.summary.json"
}
returnThisStatusCode
Integer
Optional

The status code to return

{
"returnThisStatusCode" : 302
}
thisManyTimes
Integer
Optional

The number of times this endpoint should be invoked This will default to 1

{
"thisManyTimes" : 2
}
whenThisIsCalled
String
Required

Required The complete url that the mock server will listen for.

The "mockserver" host is replaced out to the actual host and port for the mock server.

{
"whenThisIsCalled" : "http://mockserver/controller/restui/licenseRule/getAllRulesSummary"
}
withMethod
String
Optional

The method expected ie GET, POST etc This will default to GET and if an expectedPayload is provided it will default to POST

{
"withMethod" : "GET"
}

SendMetricVerification

Defines expected metrics to have been published from the test. If these metrics are not received the test will fail.

Pay special note to the timestamp field.

{
"theseMetricsShouldHaveBeenSent": [
{
"key": "mymetric",
"value": 67.0
}
]
}
JSON Properties

The following properties are available to set on the SendMetricVerification JSON schema.

dimensionMap
String
Optional

Assert that received and expected dimensions are exact.

{
"dimensionMap" : {
"ad" : "ad_mh"
}
}
key
String
Required

Required Assert the exact key on the metric.

{
"key" : "abcde"
}
timestamp
Integer
Optional

If set will assert the exact timestamp on the metric, otherwise the timestamp will be ignored during assertion.

{
"timestamp" : 1593658546131
}
toThisRoute
String
Optional
value
Double
Required

Required Assert the exact value on the metric.

{
"value" : "1234.56"
}

TestConfig

Describes how to execute a test and verify results

JSON Properties

The following properties are available to set on the TestConfig JSON schema.

fromDirectory
String
Required

Required The relative path from the test directory to the test resources (test workflow configurations, mock response files etc).

{
"fromDirectory" : "/mytest/"
}
ignore
Boolean
Optional

If true the test will not be run.

{
"ignore" : true
}
logsShouldNotContain
String
Optional

These logs are not expected and the test will fail if they are generated by the workflow configuration.

This is useful to ensure that secrets are not logged.

{
"logsShouldNotContain" : [
...
]
}
makeTheseCalls
co.opscotch.test.HttpCall
Optional

Make http calls to the agent and assert the response

{
"makeTheseCalls" : [
...
]
}
mockEndpointResponses
co.opscotch.test.MockHttpResponse
Required

Required Sets up a http server with mocked responses.

{
"mockEndpointResponses" : [
...
]
}
secondsToWaitForCompletion
Integer
Optional

Determines how long to wait for logs and metric assertions before the test is stopped

Defaults to 10

{
"secondsToWaitForCompletion" : 20
}
testThisStep
String
Required

Required The name of the step in the workflow configuration to trigger to start the test.

{
"testThisStep" : "start-application"
}
theseLogsShouldHaveBeenSent
String
Optional

These logs are expected and the test will fail if they are not generated by the workflow configuration

{
"theseLogsShouldHaveBeenSent" : [
...
]
}
theseMetricsShouldHaveBeenSent
co.opscotch.test.SendMetricVerification
Required

Required These metrics are expected and the test will fail if they are not generated by the workflow configuration

{
"theseMetricsShouldHaveBeenSent" : [
...
]
}
timestampOverride
Integer
Optional

If set (to a millisecond timestamp) the system clock will be set to this time.

{
"timestampOverride" : 1593658546131
}
useThisTestBootstrapFile
String
Optional

The bootstrap configuration to include for the test.

{
"useThisBootstrapFile" : "test.bootstrap.json"
}
useThisTestConfigFile
String
Required

Required The workflow configuration file to load for the test.

{
"useThisTestConfigFile" : "test.config.json"
}

TestRunnerConfig

JSON configuration required for defining test configurations against agents.

This configuration file is passed to the test runner as a command line argument and tells it where to find the tests and resource files.

JSON Properties

The following properties are available to set on the TestRunnerConfig JSON schema.

concurrency
Integer
Optional

Number of tests to run at the same time This will default to half the number of processors available or 1 if there is only one. The maximum value is the number of processors available -2 or 1 if there are less than 3 processors available

debug
Boolean
Optional

If true, will enable debug for the test

iterations
Integer
Optional

Speficies the number of times to run the tests Defaults to 1.

license
String
Required

Required The license key

resourceDir
String
Required

Deprecated: use resourceDirs

Required The path to the configuration resource directory

resourceDirs
String
Required

Required The paths to the configuration resource directories

stopOnFailure
Boolean
Optional

Indicates whether the test runner should stop executing tests after the first failure is encountered.

Defaults to false, meaning the test runner will continue executing all configured tests, regardless of whether a failure occurs.

If set to true, the test runner will immediately terminate testing upon the first failed test. Currently running tests will continue till completion.

testDir
String
Required

Deprecated: use testDirs

Required The path to the configuration test directory

testDirs
String
Required

Required The paths to the configuration test directories

opscotch Error Codes

Most errors will have an opscotch error code that may be referenced in logs, metrics or messages. Please see the list below for descriptions of error codes.

AJC1: Can not decrypt encrypted data

Occurs when encrypted data fails to decrypt in authentication context.

AS2: Invalid arguments, expecting bootstrap

The agent was started with unexpected arguments. Please check the documentation.

AS3: Agent error occurred before startup

Please report this error to opscotch

BC1: No buffer exists for key

The requested byte buffer does not exist in this context

BC2: Could not gunzip

Check that the buffer contains gzipped data

BC4: Could not unzip

Check that the buffer contains zipped data

BC5: Buffer offset overrun

Requested offset is greater than the buffer size

BC6: Buffer length overrun

Requested length is greater than the buffer size

BC7: Invalid buffer byte indexing

Requested offset and length is greater than the buffer size

BL1: Failed to load bootstrap

Generic bootstrap load failure. See additional error codes.

BL2: Duplicate deploymentId

Bootstrap loaded with a deploymentId that is already loaded.

BL3: Failed to load bootstrap - Decryption

Failed to decrypt using internal opscotch keys.

BL4: Duplicate host id

Bootstrap hosts must have unique ids.

BL5: Duplicate host id

Bootstrap hosts must have unique ids.

BL6: Required file does not exist

A bootstrap allowFileAccess is marked as required but does not exist

BL7: Duplicate key id

bootstrap.keys contains duplicate key ids

BS1: Malformed url

The url specified in Output.outputUrl is malformed.

BS2: Failed send for metrics or logs

Unexpected send failure; data likely lost.

CC10: No key found for verifySignature

The passed key or buffer id could not be found

CC11: No key found for encryptSymmetric

The passed key or buffer id could not be found

CC12: Payload must be at least 1 byte

Check the passed payload size

CC13: Could not encrypt using encryptSymmetric

Check the passed key or buffer id

CC14: No key found for decryptSymmetric

The passed key or buffer id could not be found

CC15: Payload must be at least 1 byte

Check the passed payload size

CC16: Could not decrypt using decryptSymmetric

Check the passed key or buffer id

CC17: No public key found for encryptAsymmetric

The passed key or buffer id could not be found

CC18: No secret key found for encryptAsymmetric

The passed key or buffer id could not be found

CC19: Payload must be at least 1 byte

Check the passed payload size

CC2: No key found matching criteria

The passed key or buffer id is null

CC20: Could not encrypt using encryptPublicKey

Check the passed key or buffer id

CC21: No public key found for decryptPublicKey

The passed key or buffer id could not be found

CC22: No secret key found for decryptPublicKey

The passed key or buffer id could not be found

CC23: Payload must be at least 1 byte

Check the passed payload size

CC24: Could not decrypt using decryptPublicKey

Check the passed key or buffer id

CC25: No public key found for encryptAnonymous

The passed key or buffer id could not be found

CC26: Payload must be at least 1 byte

Check the passed payload size

CC27: Could not encrypt using encryptAnonymous

Check the passed key or buffer id

CC28: No public key found for decryptAnonymous

The passed key or buffer id could not be found

CC29: No secret key found for decryptAnonymous

The passed key or buffer id could not be found

CC3: Key add failed

required: id, purpose, type, keyHex

CC30: Payload must be at least 1 byte

Check the passed payload size

CC31: Could not decrypt using decryptAnonymous

Check the passed key or buffer id

CC34: The passed key bytes are null

Check the passed key bytes

CC35: The passed byte array size are incorrect

Check the passed key bytes

CC4: Key add failed

Incorrect key length, check the key length matches the key 'purpose'

CC5: Key validation failed

required: id, purpose, type

CC7: No key found for sign

The passed key or buffer id could not be found

CC8: Payload must be at least 1 byte

Check the passed payload size

CC9: Could not generate signature

Check the passed key or buffer id

CD1: The agent private key is invalid

Decoded but not a valid RSA PKCS8 private key.

CD2: Could not read the packaged configuration

The bootstrap settings are wrong, or the package is incompatible with this agent version.

CD3: Could not decrypt config

Workflow configuration could not be decrypted.

CD4: Workflow JSON file format is not supported

Attempted to load a raw workflow json file.

CD5: Workflow config is not valid

Check packager version

CD6: Can not load a config that was packaged with an incompatible packager

Check packager version

CD9: The workflow file is empty and will not be loaded

This is generally not a problem and can happen when updating the file and the writing process truncates the file

CDE1: Workflow Configuration not loaded

Signature could not be validated even after decryption.

CP1: Workflow configuration load failed

Generic workflow configuration load failure.

CP2: Workflow configuration load failed

Generic workflow configuration load failure.

CP3: Invalid agentPrivateKey in bootstrap

Base64 decode of agentPrivateKey failed.

CP4: agentPrivateKey required in Prod Mode

Missing agentPrivateKey when running in Prod Mode.

CR1: Failed loading configuration

Failure after JSON validation when loading steps.

CR2: Step requested does not exist

Requested step has not been loaded.

CR3: Workflow did not finish active runs in time

Reload forced while runs were still active.

CRW1: Exception while checking license

Problem with the license checking mechanism.

CW1: Malformed url

Invalid URL in bootstrap remoteConfiguration.

CW2: Invalid bootstrap remote configuration settings

remoteConfigurationTimeout must be less than frequency.

FC1: Can not read file

The requested file could not be read. Check file system permissions

FC10: Not permitted to write

The requested destination file is not permitted to be written. Check bootstrap.allowFileAccess.WRITE.

FC11: Can not write file

The requested destination file could not be written to. Check file system properties.

FC12: Can not write file

The requested destination file could not be written to. Check file system properties.

FC13: Can not delete file

The requested destination file could not be deleted. Check file system properties.

FC2: Not permitted to read file

The requested file is not permitted to be read. Check bootstrap.allowFileAccess.READ.

FC3: Can not read file

The requested file could not be read. Check file system permissions

FC4: Not permitted to read file

The requested file is not permitted to be read. Check bootstrap.allowFileAccess.READ.

FC5: Not permitted to read file

The requested file is not permitted to be read. Check bootstrap.allowFileAccess.READ.

FC6: Not permitted to move file without delete permission

The requested file is not permitted to be deleted while moving. Check bootstrap.allowFileAccess.DELETE.

FC7: Source file does not exist

The requested file does not exist

FC8: Not permitted to write

The requested destination file is not permitted to be written. Check bootstrap.allowFileAccess.WRITE.

FC9: Destination file exists and no overwrite

The destination file exists and overwrite was specified.

FW1: Failed to load file

remoteConfiguration refers to a file that could not be loaded.

FW2: Failed to read file

remoteConfiguration file could not be read.

FW3: Failed to load file

File read but contents could not be processed.

FW4: Can not load zero length file

remoteConfiguration refers to a zero length file.

HF1: URI pattern already exists

URI pattern already exists on this HTTP server.

HFS1: Only http request trigger permitted on http file serving step

Remove other triggers off the http file serving step

HFS2: Http request trigger is required

Add http request trigger to the http file serving step

HFS3: Only GET method is permitted

Only GET method is permitted on the http file serving step

HFS4: Requires allowHttpServerAccess

Http file serving steps requires bootstrap.allowHttpServerAccess

HFS5: Requires allowHttpServerAccess.servePackagedAsset

Http file serving steps requires bootstrap.allowHttpServerAccess.servePackagedAsset

HFS6: Requires bootstrap.allowFileAccess

Http file serving steps requires bootstrap.allowFileAccess

HP1: Not on allow list

HTTP address not on host.allowList for path/method.

HP2: Authentication Failed

authenticationProcessor failed to complete.

HP3: Url not set

urlGenerator used but URL was not set.

HP4: Error processing HTTP response

Exception during HTTP response processing.

HP5: Error while making http request from step

HTTP request failed.

HT1: No bootstrap.allowHttpServerAccess with id

Workflow trigger attempted to attach to bootstrap.allowHttpServerAccess.id that does not exist

HT2: Invalid HTTP method

Invalid HTTP method specified in workflow trigger

HT7: Client disconnected

Http client disconnect be connection was closed

HT8: Multipart request received but httpRequestTrigger.multiPartUploadByteLimit is not set

If expecting multipart uploads ensure httpRequestTrigger.multiPartUploadByteLimit is set appropriately

HT9: Multipart upload exceeds size limit of httpRequestTrigger.multiPartUploadByteLimit

If expecting multipart uploads ensure the size of the uploaded file does not exceed the httpRequestTrigger.multiPartUploadByteLimit

HW1: Could not get Workflow configuration

HTTP resource fetch failed.

HW2: Could not get Workflow configuration

Decode failed after HTTP fetch.

IT11: Can not start file watcher

File watching is not supported on this OS or filesystem

IT12: unable to load file

An error occurred while loading a file from the file water for the step.trigger.fileWatcher

IT13: unable to load file

An error occurred while loading a file from the file water for the step.trigger.fileWatcher

IT2: Path is invalid

Check the step.trigger.fileWatcher paths

IT3: eventSplitter pattern is invalid

Check the step.trigger.fileWatcher.eventSplitter pattern

IT4: unable to load files

An error occurred while starting the file water for the step.trigger.fileWatcher

IT5: No bootstrap.allowFileAccess with id

Check the bootstrap.allowFileAccess pattern for the step.trigger.fileWatcher.bootstrapFileId

IT6: bootstrap.allowFileAccess has an invalid pattern

Check the bootstrap.allowFileAccess pattern for the step.trigger.fileWatcher.bootstrapFileId

IT7: fileTrigger.pattern has an invalid pattern

Check the step.trigger.fileWatcher.patterns

IT8: eventSplitter has an invalid pattern

Check the step.trigger.fileWatcher.eventSplitter pattern

IT9: unable to load file

An error occurred while loading a file from the file water for the step.trigger.fileWatcher

JC1: Messages failed to load

Workflow configuration messages failed to load.

JC10: getTimestamp

Error during context.getTimestamp().

JC11: getTimestampManager

Error during context.getTimestampManager().

JC12: setProperty

Error during context.setProperty().

JC13: getStepProperties

Error during context.getStepProperties().

JC14: getProperty

Error during context.getProperty().

JC15: setPersistedItem

Error during context.setPersistedItem().

JC16: getPersistedItem

Error during context.getPersistedItem().

JC17: setMessage

Error during context.setMessage().

JC18: addSplitReturnItem

Error during context.addSplitReturnItem().

JC19: getData

Error during context.getData().

JC2: getPassedMessageAsString

Error during context.getPassedMessageAsString().

JC20: setHeader

Error during context.setHeader().

JC21: getHeader

Error during context.getHeader().

JC22: delta

Error during context.delta().

JC23: regexMatch

Error during context.regexMatch().

JC24: mergeJsonStrings

Error during context.mergeJsonStrings().

JC25: xmlToJson

Error during context.xmlToJson().

JC26: jsonPath

Error during context.jsonPath().

JC27: removeHeader

Error during context.removeHeader().

JC28: setHttpMethod

Error during context.setHttpMethod().

JC29: Malformed URL

Invalid URL passed to context.setUrl().

JC3: getMessageBodyAsString

Error during context.getMessageBodyAsString().

JC30: Host not found

hostref not found in bootstrap host property.

JC31: Host not permitted

Host referenced from the wrong context.

JC32: host-ref can not be null

hostref missing when calling context.setUrl().

JC33: files

Error during context.files().

JC34: queue

Error during context.queue().

JC35: counter

Error during context.counter().

JC36: setCounter

Error during context.setCounter().

JC37: setBody

Error during context.setBody().

JC38: setStream

Error during context.setStream().

JC39: setStreamFromString

Error during context.setStreamFromString().

JC4: sendToStep

Error during context.sendToStep().

JC40: sendToStepAndForget

Error during context.sendToStepAndForget().

JC41: getBody

Error during context.getBody().

JC42: metric key is empty

The metric can not be empty

JC5: sendMetric

Error during context.sendMetric().

JC6: getAnomalyDetection

Error during context.getAnomalyDetection().

JC7: sendMetric

Error during context.sendMetric().

JC8: sendMetric

Error during context.sendMetric().

JC9: diagnosticLog

Error during context.diagnosticLog().

JSS1: docs.run(...) is not a function

Ensure that a function is passed to docs.run()

JSS2: Error parsing schema

Check that a valid jsonschema is passed

JSS3: Error parsing schema

Check that a valid jsonschema is passed

JSS4: Unknown schema type

Check that a valid jsonschema is passed

OHC1: Unhandled Exception

Unhandled exception during HTTP response processing.

OHC2: Unhandled Exception

Unhandled exception during HTTP failure.

OMR1: Error while closing Agent Metric Sender

Error occurred while closing Agent Metric Sender.

PS4: Persistence directory does not exist

Ensure that the bootstrap.persistenceRoot is set to a directory that exists

PV1D1: Unable to read package

Unable to read package, check the packager is up to date with the agent.

PV1D2: Could not decrypt package

Check that the agent private key matches the packaging public key

PV1D3: Could not verify the author

The workflow configuration could not be verified, check the packager is up to date with the agent

PV1D4: The agent private key is invalid

Expected a base64 encoded RSA PKCS8

PV1D5: Unable to read package

Unable to read package, check the packager is up to date with the agent.

PV1D6: Unable to read package

Unable to read package, check the packager is up to date with the agent.

PV2D17: Unable to read package

Unable to read package, check the packager is up to date with the agent.

SE1: Could not create persistence

persistenceFile defined but file could not be created.

SE10: Error validating output against outSchema

Check you output matches the declared schema

SE2: Ending Run

Run ended prematurely and was not completed.

SE3: Unhandled Exception - Please report this to opscotch support

Run ended prematurely and exception handler failed.

SE4: Workflow configuration was updated

Run did not complete before configuration update.

SE5: Ending Run

Likely caused by JavaScript in executing step processor.

SE6: Persistence requested but not setup

Processor called persistence but it was not set up.

SE7: TimestampManager requires persistence

TimestampManager requires persistence, but it was not set up

SE8: Error validating input against inSchema

Check you input matches the declared schema

SE9: Error validating input against dataSchema

Check you data matches the declared schema

T2: OpenTelemety endpoint and type must be set

Check OPSCOTCH_OTEL_PROPERTIES environment variable