API Reference
This documentation describes the functionality that is available for configuration authors.
Documentation describing the functionality and schema of configuration (workflow, bootstrap etc.) is referred to as the model and is available below.
Documentation describing the functionality and schema of the testing harness is available below.
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 Bootstrap 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
StringRequired 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
HostA 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
FilePermitterA 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
HttpServerPermitterA 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
ObjectA 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
StringRequired 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
BooleanDisable is bootstrap by setting enabled : false
Defaults to true
{
"enabled": false
}
errorHandling
ErrorHandlingDetermines the behavior of error handling while loading the main configuration
{
"errorHandling": {
...
}
}
frequency
IntegerWhen 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
OldHostDEPRICATED: 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
KeyOptional 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
StringAn 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
StringA licensing pool id configured on the opscotch licensing app.
Defaults to "default".
{
"licenseHostPoolId" : "anotherPool"
}
packaging
PackagingpersistenceRoot
StringDefines the filesystem storage root for persistence
{
"persistenceRoot": "/storage"
}
reloadTimeout
IntegerDefines 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
StringRequired 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
StringWhen using a URL remoteConfiguration, setting this property will set the "Authorization" header
{
"remoteConfiguration": "http://www.example.com",
"remoteConfigurationAuth" : "xodsjfujrhdjfk",
"frequency" : 60000
}
remoteConfigurationTimeout
IntegerWhen 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
WorkflowOutputsDetermines 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
BooleanEnable or disables logging of errors and information to the agent standard out
Defaults to true
{
"enableLocalLogging": true
}
logs
OutputDefines 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
OutputDefines 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
StringDefines 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
BooleanWhen true files will be deletable.
Defaults to false
{
"DELETE": true
}
directoryOrFile
StringA 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
StringAn id that must be unique to this bootstrap.
Use this id in the workflow step file trigger.
{
"id": "myTextFiles"
}
LIST
BooleanWhen true files will be listable.
Defaults to false
{
"LIST": true
}
patterns
String[]A list of (Java) Regular Expressions that can be used to further restrict access to files in the directory
{
"patterns": [
".*\\.txt$",
".*\\.log$"
]
}
READ
BooleanWhen true files will be readable.
Defaults to false
{
"READ": true
}
required
BooleanWhen true the file or directory must exist otherwise an error is thrown.
Defaults to false
{
"required": true
}
WRITE
BooleanWhen 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
HostAllowA 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
BooleanWhen 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
ObjectA 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
StringA object of HTTP headers to be sent with every call.
{
"headers": {
"Content-Type": "application/json;charset=UTF-8",
"Accept": "application/json, text/plain, *\/*"
}
}
host
StringRequired A URL that is used as the base for constructing URLs to call.
{
"host": "https://www.example.com:8080"
}
id
StringRequired 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
StringHTTP Method to match on. One of:
- GET
- HEAD
- POST
- PUT
- DELETE
- OPTIONS
- PATCH
{
"method": "GET"
}
uriPattern
StringRegex 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
StringRequired A unique string that identifies this http server in other configurations.
{
"id": "myAPI"
}
port
IntegerRequired A port on the host that this http server will bind to. Normal port binding rules apply.
{
"port": 1234
}
serveFromPackagedAsset
ServePackagedAssetDescribes 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
StringRequired A unique identifier used to reference a specific key
keyHex
StringRequired The hex encoded key
metadata
StringAdditional metadata used solely for ease of key management in the bootstrap. This metadata is not loaded into the agent.
purpose
StringRequired 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
StringRequired 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[]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
BooleanWhen 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
ObjectA 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
StringA object of HTTP headers to be sent with every call.
{
"headers": {
"Content-Type": "application/json;charset=UTF-8",
"Accept": "application/json, text/plain, *\/*"
}
}
host
StringRequired 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
BooleanEnables or disables the sending of data.
Defaults to false
{
"enabled": true
}
outputAuthorization
StringSet the "Authorization" header.
{
"outputAuthorization" : "xodsjfujrhdjfk"
}
outputUrl
StringRequired The URL that data is transmitted to.
{
"outputUrl": "http://www.example.com"
}
persistenceRoot
StringIf set, defines the location to store output queue files
{
"persistenceRoot" : "/tmp/output-queues"
}
routingToken
StringRequired 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
KeyOptional 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
StringOptional 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
StringOptional 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
IntegerOptional 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
KeyOptional 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
StringIdentifies 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
ObjectA 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
WorkflowRequired 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
ErrorHandlingDetermines the behavior of error handling while running the main configuration
{
"errorHandling": {
...
}
}
metricOutput
OutputMetrics 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 Workflow Package:
Scripting context objects in the Workflow Package:
- AuthenticationJavascriptContext
- ByteBufferHandle
- ByteContext
- ByteReader
- CryptoContext
- DiagnosticsContext
- FilesContext
- JavascriptContext
- JavascriptStateContext
- PersistentQueueContext
- TimestampManager
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
StringDefines the allowed file access from the bootstrap
This must match an id in a bootstrap.allowFileAccess.id
{
"bootstrapFileId": "myTestFiles"
}
eventSplitter
StringDefines 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
BooleanWhen true these executions will be omitted from tracing (monitoring)
patterns
String[]A list of (Java) regular expressions used for file selection
{
"patterns": [
".+\\.txt$",
".+\\.log$"
]
}
splitAtEnd
BooleanWhen 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
StringThe HTTP method to listen for.
Defaults to GET
{
"method": "POST"
}
multiPartUploadByteLimit
IntegerLimits multipart uploads to this number of bytes
NOTE: setting this enables multipart uploads for this endpoint
noTrace
BooleanWhen true these executions will be omitted from tracing (monitoring)
path
StringA regular expression that matches against the URI path
{
"path": "/api/.*"
}
server
StringIdentifies 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
ObjectA 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
StringA file path to the script to execute.
Must be supplied if JavaScriptSource.script is not supplied
{
"resource": "scripts/myscript.js"
}
script
StringThe 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
JavaScriptSourceA 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
IntegerHARD CODED TO 5MB
maxMemoryBytes
IntegerHARD CODED TO 1MB (1024 * 1024)
queuefilePrefix
StringHARD 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:
-
Optionally generate a URL (urlGenerator)
-
Optionally (requires a url to have been set) generate a payload (payloadGenerator)
-
Optionally perform authentication steps (authenticationProcessor, call other steps to perform authentication)
-
Optionally call out to a named Bootstrap Host with the generated URL and payload
-
Optionally handle specific HTTP status codes with httpStatusHandling
OR
-
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:
-
transforming the input into a list (splitGenerator)
-
calling a URL with each item in the list:
-
Optionally generate a URL (urlGenerator)
-
Optionally (requires a URL to have been set) generate a payload (payloadGenerator)
-
Optionally perform authentication steps (authenticationProcessor, call other steps to perform authentication)
-
Optionally call out to a named Bootstrap Host with the generated URL and payload
-
Optionally handle specific HTTP status codes with httpStatusHandling
OR
-
Optionally Process each item's response (itemResultProcessor)
-
Collect the result into a response list
-
-
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, andresultsProcessor
-
-
"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
httptrigger to be defined, an only allowsGETrequests
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
JavascriptProcessorThis 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
ObjectA 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
BooleanEnables or disables the debug logs for this step. Defaults to false.
{
"debug": true
}
enabled
BooleanEnables or disables the execution of this step. Defaults to true.
{
"enabled": true
}
httpConnectFailedProcessor
JavascriptProcessorDefines how to handle HTTP connection failures using a standard processor
{
"httpConnectFailedProcessor": {
...
}
}
httpStatusHandling
JavascriptProcessorA 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
IntegerSet the http timeout period in milliseconds
Defaults to 10000 (10 seconds)
{
"httpTimeout" : 10000
}
itemResultProcessor
JavascriptProcessorWhen using Step.type "scripted-split-aggregate", defines if and how to process items before they're added to the list.
{
"itemResultProcessor": {
...
}
}
payloadGenerator
JavascriptProcessorDefines 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
StringDefines 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
JavascriptProcessorRequired 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
StringDetermines 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
JavascriptProcessorWhen using Step.type "scripted-split-aggregate", defines how to generate the list to be operated on.
{
"splitGenerator": {
...
}
}
stepId
StringRequired Sets the id of the step.
Must be unique.
{
"stepId": "the-first-step-in-my-route"
}
timer
StringDepricated: 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
TriggerDefines how a workflow is started.
{
"trigger": {
...
}
}
type
StringSets 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
JavascriptProcessorRequired 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
IntegerDefines a delay in milliseconds before the first invocation.
Defaults to 0.
{
"delay": 60000
}
noTrace
BooleanWhen true these executions will be omitted from tracing (monitoring)
period
IntegerDefines 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
FileWatchingTriggerDefines a trigger that fires when new lines are added to a file.
{
"fileWatcher": {
...
}
}
http
HttpRequestTriggerDefines a trigger that fires when a matching http request is received.
{
"http": {
...
}
}
runOnce
BooleanSets trigger to run only once.
Defaults to false
{
"runOnce": true
}
runOnceNoTrace
BooleanWhen true these executions will be omitted from tracing (monitoring)
timer
TimerDefines 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
ObjectA 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
BooleanEnable or disables the loading of the route.
Defaults to true
{
"enabled": false
}
name
StringRequired The user friendly name of the route.
{
"name": "my route"
}
steps
StepAuthenticationJavascriptContext
This is a specialised Javascript Context for authentication steps.
All the methods on Javascript Context are still available, the methods listed below are specialisations.
Methods
The following methods are available to call on the `` object.
- String getAuthenticationPropertiesFromStep (String stepId, String key)
- String getRestrictedDataFromHost (String host)
- void setAuthenticationPropertiesOnStep (String stepName, Long expiresInMs, String key, String authenticationProperties)
GetAuthenticationPropertiesFromStep
String getAuthenticationPropertiesFromStep (String stepId, String key)
ACCESSES RESTRICTED DATA
Gets the authentication properties from another step. These properties can expire.
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"));
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.
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.
- ByteBufferHandle base64ToBinary (String base64)
- String binaryToBase64 (ByteBufferHandle buffer)
- String binaryToHex (ByteBufferHandle buffer)
- ByteBufferHandle concat (ByteBufferHandle[] buffers)
- ByteBufferHandle copy (ByteBufferHandle sourceBuffer)
- ByteBufferHandle create (Integer size)
- ByteBufferHandle createFromByteArray (Byte[] bytes)
- ByteBufferHandle createFromString (String string)
- Integer getSize (ByteBufferHandle buffer)
- ByteBufferHandle gunzip (ByteBufferHandle buffer)
- ByteBufferHandle gzip (ByteBufferHandle buffer)
- ByteBufferHandle hexToBinary (String hex)
- Integer readByte (ByteBufferHandle fromBuffer, Integer offset)
- ByteReader reader (ByteBufferHandle buffer)
- ByteReader reader ()
- void release (ByteBufferHandle[] buffers)
- ByteBufferHandle resize (ByteBufferHandle buffer, Integer newSize)
- ByteBufferHandle slice (ByteBufferHandle sourceBuffer, Integer offset, Integer length)
- ByteBufferHandle unzip (ByteBufferHandle buffer)
- void writeByte (ByteBufferHandle buffer, Integer offset, Integer value)
- void writeBytes (ByteBufferHandle toBuffer, Integer offset, ByteBufferHandle sourceBuffer, Integer sourceOffset, Integer length)
- ByteBufferHandle zip (ByteBufferHandle buffer)
Base64ToBinary
ByteBufferHandle base64ToBinary (String base64)
Converts a Base64 encoded String into a binary buffer.
BinaryToBase64
String binaryToBase64 (ByteBufferHandle buffer)
Converts buffer contents to a Base64 encoded string.
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);
}
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]
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)
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
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
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);
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));
}
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);
}
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
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);
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);
}
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
Reader
ByteReader reader ()
Reads from the context stream
Release
void release (ByteBufferHandle[] buffers)
Securely releases buffers from memory.
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);
}
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);
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
}
}
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;
}
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]
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);
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.
Read
ByteBufferHandle read (Integer length)
Reads the specified number of bytes from the current position into a new buffer.
ReadAll
ByteBufferHandle readAll ()
Reads all the available bytes from the current position into a new buffer.
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.
- ByteBufferHandle decryptAnonymous (ByteBufferHandle payloadBytes, String registeredPublicKeyId, String registeredPrivateKeyId)
- ByteBufferHandle decryptPublicKey (ByteBufferHandle payloadBytes, ByteBufferHandle nonceBytes, String registeredPublicKeyId, String registeredPrivateKeyId)
- ByteBufferHandle decryptSymmetric (ByteBufferHandle encryptedBytes, ByteBufferHandle nonceBytes, String registeredSharedKeyId)
- ByteBufferHandle encryptAnonymous (ByteBufferHandle payloadBytes, String registeredPublicKeyId)
- ByteBufferHandle encryptPublicKey (ByteBufferHandle payloadBytes, ByteBufferHandle nonceBytes, String registeredPublicKeyId, String registeredPrivateKeyId)
- ByteBufferHandle encryptSymmetric (ByteBufferHandle payloadBytes, ByteBufferHandle nonceBytes, String registeredSharedKeyId)
- ByteBufferHandle[] generateKeyPair (String purpose)
- ByteBufferHandle hash (ByteBufferHandle input)
- ByteBufferHandle randomBytes (Integer length)
- String registerKey (String purpose, String type, String keyHex)
- ByteBufferHandle sign (ByteBufferHandle payloadBytes, String registeredKeyId)
- Boolean validateKey (String id, String purpose, String type)
- Boolean verifySignature (ByteBufferHandle signatureBytes, ByteBufferHandle messageBytes, String registeredPublicKeyId)
DecryptAnonymous
ByteBufferHandle decryptAnonymous (ByteBufferHandle payloadBytes, String registeredPublicKeyId, String registeredPrivateKeyId)
Decrypts a payload using anonymous public-key encryption.
DecryptPublicKey
ByteBufferHandle decryptPublicKey (ByteBufferHandle payloadBytes, ByteBufferHandle nonceBytes, String registeredPublicKeyId, String registeredPrivateKeyId)
Decrypts a payload using authenticated public-key encryption.
DecryptSymmetric
ByteBufferHandle decryptSymmetric (ByteBufferHandle encryptedBytes, ByteBufferHandle nonceBytes, String registeredSharedKeyId)
Decrypts a payload using symmetric decryption.
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.
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.
EncryptSymmetric
ByteBufferHandle encryptSymmetric (ByteBufferHandle payloadBytes, ByteBufferHandle nonceBytes, String registeredSharedKeyId)
Encrypts a payload using symmetric encryption.
GenerateKeyPair
ByteBufferHandle[] generateKeyPair (String purpose)
Generate a new public/private key pair for the given type
Hash
ByteBufferHandle hash (ByteBufferHandle input)
Generates a consistent hash for the same input
RandomBytes
ByteBufferHandle randomBytes (Integer length)
Generates random bytes that are cryptographically secure.
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
signandverifySignatureusing public/secret keys - authenticated - used for
encryptPublicKeyanddecryptPublicKeyfor mutually authenticated public-key encryption - symmetric - used for
encryptSymmetricanddecryptSymmetric- this only uses a secret key - anonymous - used for
encryptAnonymousanddecryptAnonymous- 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");
Sign
ByteBufferHandle sign (ByteBufferHandle payloadBytes, String registeredKeyId)
Signs a payload using a secret key and returns the signature.
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
VerifySignature
Boolean verifySignature (ByteBufferHandle signatureBytes, ByteBufferHandle messageBytes, String registeredPublicKeyId)
Verifies that a signature matches a message using a public key.
DiagnosticsContext
An interface for interacting with logging/tracing/monitoring
Methods
The following methods are available to call on the context.diagnostic() object.
- void errored (String error)
- void errored (String type, String error)
- void event (String event)
- void setAttribute (String key, String value)
- void setAttribute (String key, Integer value)
- void setAttribute (String key, Double value)
Errored
void errored (String error)
Mark the trace as errored and records the error message
Errored
void errored (String type, String error)
Mark the trace as errored and records the error type and message
Event
void event (String event)
Add an event to a trace
SetAttribute
void setAttribute (String key, String value)
Set an attribute onto the trace
SetAttribute
void setAttribute (String key, Integer value)
Set an attribute onto the trace
SetAttribute
void setAttribute (String key, Double value)
Set an attribute onto the trace
FilesContext
The FileContext provides workflow access to files.
The FileContext is got via context.files(fileId) method.
Only files defined in the bootstrap allowFileAccess property can be accessed.
Methods
The following methods are available to call on the context.files() object.
- void copy (String srcPath, String dstFileId, String dstPath, Boolean mkdir, Boolean overwrite)
- void delete (String file)
- String list (String path)
- void move (String srcPath, String dstFileId, String dstPath, Boolean mkdir, Boolean overwrite)
- String read (String file)
- ByteReader reader (String file)
- void write (String file, String body)
- void writeBinary (String file, ByteBufferHandle buffer, Long offSet)
Copy
void copy (String srcPath, String dstFileId, String dstPath, Boolean mkdir, Boolean overwrite)
Copies a file from one location to another
Delete
void delete (String file)
Delete a file
List
String list (String path)
Lists the directory
Move
void move (String srcPath, String dstFileId, String dstPath, Boolean mkdir, Boolean overwrite)
Moves a file from one location to another
Read
String read (String file)
Read the contents of the file as a string
Reader
ByteReader reader (String file)
Creates a byte reader on the contents of the file
Write
void write (String file, String body)
Write the string contents to a file
WriteBinary
void writeBinary (String file, ByteBufferHandle buffer, Long offSet)
Write the binary contents from the byte buffer to a file
JavascriptContext
This is the entry point to the agent functionality from javascript.
Methods
The following methods are available to call on the context object.
- void addSplitReturnItem (String item)
- void addSystemError (String error)
- void addUserError (String error)
- ByteContext bytes ()
- Double counter (String name, Double add)
- CryptoContext crypto ()
- Double delta (String key, Double currentValue)
- DiagnosticsContext diagnostic ()
- void diagnosticLog (String message)
- void end ()
- FilesContext files (String id)
- String getBody ()
- String getData ()
- String getData (String key)
- String getHeader (String name)
- String getMessageBodyAsString ()
- String getPassedMessageAsString ()
- String getPersistedItem (String key)
- Object getProperty (String key)
- Object getStepProperties ()
- ByteReader getStream ()
- Long getTimestamp ()
- TimestampManager getTimestampManager ()
- String hash (String toHash)
- String jsonPath (String json, String expression)
- String mergeJsonStrings (String one, String two)
- PersistentQueueContext queue ()
- String regexMatch (String regex, String input)
- void removeHeader (String name)
- void sendMetric (String key, Double value)
- void sendMetric (String routingToken, Long timestamp, String key, Double value, String metadata)
- void sendMetric (Long timestamp, String key, Double value)
- void sendMetric (Long timestamp, String key, Double value, String metadata)
- JavascriptStateContext sendToStep (String stepName, String body)
- JavascriptStateContext sendToStep (String stepName, String body, String headers)
- void sendToStepAndForget (String stepName, String body)
- void sendToStepAndForget (String stepName, String body, String headers)
- void setBody (Object body)
- void setCounter (String name, Double value)
- void setData (String data)
- void setHeader (String name, Object value)
- void setHttpMethod (String method)
- void setMessage (Object message)
- void setPersistedItem (String key, String value)
- void setProperty (String key, Object value)
- void setStream (ByteReader reader)
- void setStreamFromString (String streamString)
- void setUrl (String hostref, String path)
- void sleep (Long ms)
- String xmlToJson (String xml)
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");
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.
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.
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
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);
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");
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
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());
GetData
String getData (String key)
data = context.getData(key);
GetHeader
String getHeader (String name)
Get a header from the previous request/response
headerArray = context.getHeader("aHeader");
header = headerArray[0];
GetMessageBodyAsString
String getMessageBodyAsString ()
Get the current message body, this could be the response from an http call for example
body = context.getMessageBodyAsString();
GetPassedMessageAsString
String getPassedMessageAsString ()
Get the message body that was passed to this step.
passedMessage = context.getPassedMessageAsString();
GetPersistedItem
String getPersistedItem (String key)
Gets an item from the step persistence
item = context.getPersistedItem("myItem");
GetProperty
Object getProperty (String key)
Gets a property from this running context
property = context.getProperty("aKey");
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");
GetStream
ByteReader getStream ()
Get the stream on the context.
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())
GetTimestampManager
TimestampManager getTimestampManager ()
The timestamp manager allows for persistence of timestamps
tm = context.getTimestampManager();
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");
JsonPath
String jsonPath (String json, String expression)
Returns the result from a JSONPath expression
MergeJsonStrings
String mergeJsonStrings (String one, String two)
Returns a merged json string
RegexMatch
String regexMatch (String regex, String input)
Returns the regex matches
RemoveHeader
void removeHeader (String name)
Remove a header from the current state
context.removeHeader("aHeader");
SendMetric
void sendMetric (String key, Double value)
Send a metric
context.sendMetric("theKey", 123);
SendMetric
void sendMetric (String routingToken, Long timestamp, String key, Double value, String metadata)
Send a metric
context.sendMetric("theRoutingToken", theTimestamp, "theKey", 123, { "someMeta" : "Data"});
SendMetric
void sendMetric (Long timestamp, String key, Double value)
Send a metric
context.sendMetric(theTimestamp, "theKey", 123);
SendMetric
void sendMetric (Long timestamp, String key, Double value, String metadata)
Send a metric
context.sendMetric(theTimestamp, "theKey", 123, { "someMeta" : "Data"});
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");
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"});
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");
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"});
SetBody
void setBody (Object body)
An alias for setMessage(...)
context.setBody("hello");
SetCounter
void setCounter (String name, Double value)
Atomically set the counter to an absolute value
SetData
void setData (String data)
Set the JSON data for this step
context.setData(JSON.stringify(data));
SetHeader
void setHeader (String name, Object value)
Add a header to the next http request
context.setHeader("aHeader", "aValue");
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");
SetMessage
void setMessage (Object message)
Sets the message body for this running exchange
context.setMessage("hello world");
SetPersistedItem
void setPersistedItem (String key, String value)
Sets an item to the step persistence
context.setPersistedItem("myItem", "theValue");
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");
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
SetStreamFromString
void setStreamFromString (String streamString)
Sets a stream from a string
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");
Sleep
void sleep (Long ms)
Force the currently running script to sleep for the given milliseconds
context.sleep(100);
XmlToJson
String xmlToJson (String xml)
Returns a json string from an xml string
JavascriptStateContext
Methods
The following methods are available to call on the returnedContext object.
- String getAllErrors ()
- String getBody ()
- String getFirstError (String errors)
- String getMessageBodyAsString ()
- Object getProperty (String key)
- Object getStepProperties ()
- String getSystemErrors ()
- String getUserErrors ()
- Boolean hasSystemErrors ()
- Boolean hasUserErrors ()
- Boolean isErrored ()
GetAllErrors
String getAllErrors ()
GetBody
String getBody ()
GetFirstError
String getFirstError (String errors)
GetMessageBodyAsString
String getMessageBodyAsString ()
GetProperty
Object getProperty (String key)
GetStepProperties
Object getStepProperties ()
GetSystemErrors
String getSystemErrors ()
GetUserErrors
String getUserErrors ()
HasSystemErrors
Boolean hasSystemErrors ()
HasUserErrors
Boolean hasUserErrors ()
IsErrored
Boolean isErrored ()
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
The following methods are available to call on the `` object.
- void push (String item)
- void pushArray (java.util.Collection<String> array)
- void returnArray (java.util.Collection<String> array)
- void returnItem (String item)
- String take (Integer count)
Push
void push (String item)
Add an item to the end of the persistent queue.
context.queue().push("adding item");
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"]);
ReturnArray
void returnArray (java.util.Collection<String> array)
Return the array items to the head of the queue
ReturnItem
void returnItem (String item)
Return the item to the head of the queue
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);
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
The following methods are available to call on the `` object.
- Long firstTimestamp ()
- Long get ()
- Long get (String key)
- Integer minutesAgo (Long timestamp)
- void set (String timestamp)
- void set (String key, String timestamp)
- void setIfLastest (String key, String timestamp)
FirstTimestamp
Long firstTimestamp ()
Get
Long get ()
Get
Long get (String key)
MinutesAgo
Integer minutesAgo (Long timestamp)
Set
void set (String timestamp)
Sets the timestamp without a key see: set(String key, String timestamp)
Set
void set (String key, String timestamp)
Sets the timestamp for the given key
SetIfLastest
void setIfLastest (String key, String timestamp)
Only performs the set operation if the passed timestamp is later than the previously stored.
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
}