View Source Runbox.Scenario.OutputAction (runbox v17.1.0)
Output action represents a side effect produced by a run.
Creating output actions
Creating output action typically happens from scenario. It is done by creating one of the appropriate struct:
Runbox.Scenario.OutputAction.UpsertAssetAttributes.t/0
Runbox.Scenario.OutputAction.DeleteAssetAttributes.t/0
Runbox.Scenario.OutputAction.DeleteAllAssetAttributes.t/0
Runbox.Scenario.OutputAction.UpsertEdge.t/0
Runbox.Scenario.OutputAction.DeleteEdge.t/0
Runbox.Scenario.OutputAction.Notification.t/0
Runbox.Scenario.OutputAction.Event.t/0
Runbox.Scenario.OutputAction.ExecuteSQL.t/0
Runbox.Scenario.OutputAction.Incident.t/0
Runbox.Scenario.OutputAction.IncidentPatch.t/0
For example:
iex> %OutputAction.UpsertAssetAttributes{
...> type: "/asset/camera",
...> id: "one",
...> attributes: %{"foo" => "bar"}
...> }
Asset and edge output actions
Changes done by output actions to assets and edges are scoped for each scenario run. The global result is computed from the changes done by individual runs.
A single run is forbidden to do multiple changes to the same object (asset attribute or edge) at the same time. However distinct runs can perform such changes, because they are scoped to each run.
The rules to compute the global state apply in the following order:
Change with the higher timestamp has precedence.
Updating an asset attribute or an edge has precedence to deleting it.
Change with the higher value has precedence (applies only for asset attributes).
Summary
Types
Attribute - access tag mapping.
Asset ID.
Asset type.
String with interpolation support.
Output Action
Types
@type access_tag() :: String.t()
@type access_tags() :: %{ required(attribute :: :all | String.t() | [String.t()]) => access_tag() | [access_tag()] }
Attribute - access tag mapping.
Access tags are defined as map where keys are attributes and values are tags of these attributes.
Attributes (keys) can be defined as:
:all
- all attributes in this upsert share the same access tagsString.t()
- single attribute access tags definition[String.t()]
- list of attributes that share the same access tags
Access tags (values) can be defined by single access tag or list of access tags.
Using this map structure we can define shared access tag for multiple attributes as well as multiple access tag for single attribute (or combination of both).
Attributes can be defined with dot
syntax (e.g. user.contact.address.street
)
where nested attributes are separated by .
. We can use this syntax to define
access tags for group of nested attributes - access tags defined for
user.contact.address
will be used for all nested attributes such as
user.contact.address.city
and user.contact.address.street
.
For delete operations: DeleteAllAssetAttributes
,DeleteAssetAttributes
and DeleteEdge
it is recommended to use the same access tags as those used for the corresponding upsert
operations within the same run.
Overlapping access tags definitions are concatenated. For example access tags defined as:
%UpsertAssetAttributes{
...
access_tags: %{
all: ["tag1"],
"user.contact" => ["tag2"],
["user.contact.address", "user.contact.phone"] => ["tag3"],
"user.contact.address.street" => "tag4"
}
}
would mean that:
"user.contact"
has these tags defined["tag1", "tag2"]
"user.contact.address.phone"
has these tags defined["tag1", "tag2", "tag3"]
"user.contact.address.street"
has these tags defined["tag1", "tag2", "tag3", "tag4"]
@type asset_id() :: String.t()
Asset ID.
Asset ID together with an asset type uniquely identifies an asset.
Asset ID must not contain any slashes. They can contain any other character though.
For example, these are valid asset IDs: fire_alarm
, 192.168.0.142
, Meeting room
, and
Příliš žluťoučký kůň
.
@type asset_type() :: String.t()
Asset type.
Assets are grouped by their asset types. Assets of the same type should be of similar nature (e.g. servers or buildings) and should share the same set of attributes.
Asset types must start with a slash and must not end with a slash. Slashes can be used
within the asset type to denote structure. For example, these are valid asset types:
/assets/servers
, /servers
, and /assets/network/routers
.
Although asset types like /servers
are permitted, it is recommended to prefix asset types
with the /assets
prefix to enable consistent configuration of common attributes (e.g., name
)
via the root /assets
asset type in the UI.
@type edge_type() :: String.t()
@type interpolable() :: String.t()
String with interpolation support.
Supports interpolating asset references to a format which is useful for displaying assets in the Altworx UI. The string can contain any number of placeholders in format
${assets.["/assets/camera", "one"]}
Where "/assets/camera"
is the asset type and "one"
is the asset ID. The resulting interpolation is
[Camera One[/assets/camera/one]]
Where Camera One
is the asset's name
attribute and /assets/camera/one
is the asset's full ID. When the asset name
is not present, the asset's ID
is used instead
[one[/assets/camera/one]]
When the asset cannot be found, the resulting interpolation is
unknown
The interpolation is done upon "read" operations, therefore the result can vary based on the asset visibility for the identity of the user performing the operation.
@type oa_params() :: Runbox.Scenario.OutputAction.UpsertAssetAttributes.t() | Runbox.Scenario.OutputAction.DeleteAssetAttributes.t() | Runbox.Scenario.OutputAction.DeleteAllAssetAttributes.t() | Runbox.Scenario.OutputAction.UpsertEdge.t() | Runbox.Scenario.OutputAction.DeleteEdge.t() | Runbox.Scenario.OutputAction.Notification.t() | Runbox.Scenario.OutputAction.Event.t() | Runbox.Scenario.OutputAction.ExecuteSQL.t() | Runbox.Scenario.OutputAction.Incident.t() | Runbox.Scenario.OutputAction.IncidentPatch.t()
@type t() :: %Runbox.Scenario.OutputAction{ body: oa_params() | Runbox.Scenario.OutputAction.BadOutputAction.t(), run_id: term(), scenario_id: term(), timestamp: integer() }
Output Action
This struct is produced by Runbox.Runtime.Stage.Sandbox.execute_run/3
.