Skip to content

Action Templates

Christian Gassner edited this page Jul 30, 2021 · 46 revisions

Action templates define unique steps which can then be reused and combined to form scenarios. Depending on the type of the action, different parameters may be provided. All parameters provided in the template can be overridden in the scenario definition. Moreover, templates provide various handy features, which can be found in the Features section.

All action types have a common set of parameters and additional parameters which are specific to ech action type.

Description of common parameters

parameter description required default
type The type of the action. Possible values are REST, WEBSOCKET, TIMER, MQTT, MQTT_PUBLISH and AMQP_LISTEN. yes
description A description for the action which is used in the log output to give additional context. no Name of the action file
invokeEvenOnFail Controls whether or not the action should be invoked even if other actons of the same scenario have already failed. Possible values are true and false. no false
allowFailure Controls whether or not a failure of this action should be considered a failure of the whole scenario. no false

Action Types

REST

A REST action is a (synchronous) HTTP call to a given endpoint. It provides functionality to validate the reponse and create variables based on the response. A validation failure is considered a failure of the action. Here is an example of the action definition:

type: REST
service: my-service
endpoint: /api/stuff
method: POST
queryParameters:
  size: 9
headers:
  Content-Type: application/json
data:
  action: "something awesome"
  offset: 237
  location:
    latitude: 11.11
    longitude: 22.22
responseValidation:
  - "res.id !== null"
  - "res.status === 'done'"
  - "head.location !== null"
variables:
  userId: "res.id"
  cookie: "head.cookie"

Description of specific parameters

parameter description required default variable and code injection
type The type of the action. Use REST for REST actions. yes no
service The host to which the HTTP request will be sent. This can be given as either an URL or a name defined in the environment configuration. Both http and https are supported. yes yes
endpoint The path of the request. yes yes
method The Request method to use for the request. Possible values are all HTTP request methods: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, CONNECT and PATCH no GET no
queryParameters Parameters which will be added as query parameters to the request. The parameters need to be provided as key–value pairs. no yes
headers HTTP headers that should be sent as part of the request. The headers need to be provided as key–value pairs. no yes
data Payload That should be sent as part of the request. The data provided will be sent as JSON. This parameter is mutually exclusive with the parameters dataBinary, form and variableAsPayload. no yes
dataBinary Path to a file that should be sent as payload as part of the request. This parameter is mutually exclusive with the parameters data, form and variableAsPayload. no no
form Payload that should be sent as part of the request. It needs to be provided as key–value pairs and will be sent as form data. Providing this parameter will also set the Content-Type header of the request to application/x-www-form-urlencoded. This parameter is mutually exclusive with the parameters data, dataBinary and variableAsPayload. no yes
variableAsPayload The name of the variable to directly use as payload. The variable must be of type string, Buffer or ReadStream. If it is not, the action will fail. This parameter is mutually exclusive with data, dataBinary and form. no no
responseValidation List of validation rules that should be applied to the response. The rules need to be provided as JavaScript expressions. The body of the response can be accessed by the res variable and the headers can be accessed by the head variable. If one of the rules fails (i.e. the expression evaluates to a falsy value), the action fails. See also Response validation. no [] no
variables The variables to store from the response of the request. This parameter needs to be given as key–value pairs where the key is the name of the variable to store and the value is a JavaScript expression. The body of the response can be accessed by the res variable and the headers can be accessed by the head variable. See also Variables. no no
clientCertificate The client certificate to use for authentication. This can either be provided inline or as a path to a certificate file prefixed by the the string file:. The certificate needs to be in PEM format. Only works when using HTTPS. no yes
clientKey The private key for the client certificate to use for authentication. This can either be provided inline or as a path to a key prefixed file by the the string file:. The key needs to be in PEM format. Only works when using HTTPS. no yes
expectBinaryResponse Whether or not the response body is expected to be of binary format. Possible values are true and false. If set to true, the response body will be treated as Buffer, otherwise it is treated as string encoded in UTF-8. no false no
diagramConfiguration Configuration for representation of the action in any drawn diagrams. Currently supports the fields hiddenFields (a list of fields to be hidden) and hidePlaintext (whether or not to hide plaintext pailoads). no {hiddenFields: [], hidePlaintext: false} no

WebSocket

Simple WebSocket client publishing an optional message on connect and listening to incoming messages. Example:

type: WEBSOCKET
service: my-service
endpoint: /api/updates/live
headers:
  userId: abc123
data:
  ping: request
expectedNumberOfMessages: 3
messageFilter:
- "msg.ping === 'response'"
- "msg.state === 'updated'"

Following promoters are allowed:

  • type: use WEBSOCKET here
  • service: host to which it should be connected
  • endpoint: endpoint of the WS server on the host
  • headers: (optional) key-value parameters which will be converted into query params and will be attached to the server url
  • data: (optional) payload which will be converted into JSON message and will be send to server if successfully connected
  • expectedNumberOfMessages: after successful connection, the WS connection will be preserved (even reconnections are handled) until the end of the whole scenario and the action will listen to incoming messages and count (uniquely) those which meet the filter criteria defined in messageFilter parameter. At the end of the scenario, it will compare the counted number with this param and log ERROR if the expected number is not equal to it. This will be changed in the future that the action fails if the number of messages is not equal.
  • messageFilter: (optional) list of filter criteria which should be met when accepting the incoming WS messages. All list elements are OR-combined. If no filter is defined, all messages will be accepted / counted.
  • diagramConfiguration: Configuration for representation of the action in any drawn diagrams. Currently supports the fields hiddenFields (a list of fields to be hidden) and hidePlaintext (whether or not to hide plaintext pailoads).

MQTT Subscribe

MQTT client which can subscribe to a broker an listen to incoming messages. Example:

type: MQTT
url: "tcp://localhost:1883"
username: admin
password: admin123
durationInSec: 60
topic: "home/temperature/kitchen"
messageType: proto
protoFile: "src/proto/atHome.proto"
protoClass: Home
expectedNumberOfMessages: 1
messageFilter:
- "msg.user.userId === 'uuid1123'"

Following attributes can be used here:

  • type: use MQTT here
  • url: broker address where to connect to
  • allowInsecure: (optional) allows insecure SSL traffic if enabled.
  • username: (optional) username if connection requires authentication
  • password: (optional) password if connection requires authentication
  • durationInSec: since it's an asynchronous action, you have to define how long the subscription should be active. The client closes the connection after that time and will no longer receive messages.
  • topic: mqtt topic where to subscribe to
  • messageType: encoding type of the incoming messages - must be one of [json, proto]
  • protoFile: (optional) if messageType was set to proto, all incoming messages will be decoded using the schema defined in the .proto file where this path directs to
  • protoClass: (optional) main message type needed for the decoding of proto messages
  • expectedNumberOfMessages: (optional) if set, incoming messages will be counted and the actual number of received messages will be compared to this expectation and if they are unequal a log message is printed. Currently the scenario does fail. This might be changes in the future.
  • messageFilter: (optional) list of evaluations which will be applied to incoming messages before counting them. Only messages which pass the evaluation will be counted & logged. If not set, ALL messages will be counted as relevant!
  • diagramConfiguration: Configuration for representation of the action in any drawn diagrams. Currently supports the fields hiddenFields (a list of fields to be hidden) and hidePlaintext (whether or not to hide plaintext pailoads)

MQTT Publish

MQTT client which can publish a defined message to the broker and finish afterwards. Example:

type: MQTT_PUBLISH
url: "tcp://localhost:1883"
username: admin
password: admin123
topic: "home/temperature/kitchen"
data:
  sensor_id: l-1
  temp: 18.33
protoFile: "src/proto/atHome.proto"
protoClass: Home

Following parameters are allowed:

  • type: use MQTT_PUBLISH here
  • url: absolute connection url to the MQTT broker
  • allowInsecure: (optional) allows insecure SSL traffic if enabled.
  • username: (optional) username if connection requires authentication
  • password: (optional) password if connection requires authentication
  • topic: topic where the message should be posted after successful connection
  • data: payload which will be converted into either JSON or protobuf - depending on the proto* parameters
  • protoFile: (optional) path to the protobuf schema needed for encoding the data structure. If not existing, data will be encoded as JSON
  • protoClass: (optional) outer / main class from the protoFile definition, which will be used for encoding
  • diagramConfiguration: Configuration for representation of the action in any drawn diagrams. Currently supports the fields hiddenFields (a list of fields to be hidden) and hidePlaintext (whether or not to hide plaintext pailoads)

AMQP Listen

AMQP client which can can consume messages from a given exchange for a given routing key on a queue (which it potentially creates itself). Similar to WebSocket actions, the AMQP listen action runs until the end of the whole scenario and the success of the action is determined by counting the number of received messages which conform to one of several given filters. The action definition looks as follows:

type: AMQP_LISTEN
broker: amqp://some.url 
exchange: myExchange
queue: testQueue
routingKey: someRoutingKey
username: foo
password: bar
expectedNumberOfMessages: 2
messageFilter:
  - "msg.id === 1234"

Description of specific parameters

parameter description required default variable and code injection
type Determines the type of the action. Use AMQP_LISTEN for AMQP_LISTEN actions. yes no
broker The address of the broker. Both amqp and amqps are supported. Alternatively, this can be a name defined in the environment configuration, similar to how the service field works for REST and WebSocket actions. yes yes
exchange The exchange from which to receive messages. yes yes
queue The queue from which to consume messages. It is assumed to be an auto deleteable queue and if it does not exist yet, it will be created. If the queue already exists with a non matching configuration, the action will fail. yes yes
routingKey The routing key to use to bind the queue to the exchange. yes yes
username The username to use for authenticating with the broker. This field is optional. no "" yes
password The password to use for authenticating with the broker. This field is optional. no "" yes
expectedNumberOfMessages The number of messages that is expected to be received. yes no
messageFilter A list of filters which define which messages are considered for expectedNumberOfMessages. The filters need to be provided as JavaScript expressions. The message can be accessed by the msg variable. A message is considered if and only if it matches one of the given filters. If no filter is given, all messages are considered. no yes
diagramConfiguration Configuration for representation of the action in any drawn diagrams. Currently supports the fields hiddenFields (a list of fields to be hidden) and hidePlaintext (whether or not to hide plaintext pailoads). no {hiddenFields: [], hidePlaintext: false} no

Node.js

An action which can evaluate arbitrary Node.js code and assign the result to variables. The given code is able to access variables with the usual {{nameOfTheVariable}} syntax. In contrast to other situations where variable injection can be used, this is not a simple string replacement but the actual variables can be accessed. This means you can correctly work with data that does not nicely convert to strings implicitly, e.g. Buffers. The action definition looks as follows:

type: NODE_JS
variables:
  foo: '"bar"' # foo will be assigned the string "bar"
  baz: '{{someVar}} + 42' # baz will be assigned the result of adding 42 to the variable someVar
  anotherVar: 'const { URL } = require("url"); new URL("http://this.is.a.test")' # anotherVar will be asigned an URL object pointing to "http://this.is.a.test"

Description of specific parameters

parameter description required default variable injection
type The type of the action. Use NODE_JS for NODE_JS actions. yes no
variables A map of variables and the expressions to evaluate and assign to them. If one of the given expressions is syntactically incorrect or throws, the action will fail. no {} yes

Timer

Use the timer action to make the framework sleep for a specific amount of time. Example:

type: TIMER
durationInSec: 5

Description of specific parameters

parameter description required default
type The type of the action. Use TIMER for TIMER actions. yes
durationInSec The amount of time to sleep for in seconds. yes