This is an automated email from the ASF dual-hosted git repository.
heneveld pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-docs.git
The following commit(s) were added to refs/heads/master by this push:
new a37e17ce docs for new workflow transforms, tidy up tips including
foreach example
a37e17ce is described below
commit a37e17ce6071356d1f8546d391cd5bdd50c643cb
Author: Alex Heneveld <[email protected]>
AuthorDate: Tue Oct 10 14:35:22 2023 +0100
docs for new workflow transforms, tidy up tips including foreach example
---
guide/blueprints/workflow/defining.md | 3 ++
guide/blueprints/workflow/settings.md | 29 ++----------
guide/blueprints/workflow/steps/steps.yaml | 43 ++++++++++++------
guide/blueprints/workflow/tips.md | 72 ++++++++++++++++++++++++++++++
guide/ops/configuration/brooklyn_cfg.md | 17 ++++---
5 files changed, 120 insertions(+), 44 deletions(-)
diff --git a/guide/blueprints/workflow/defining.md
b/guide/blueprints/workflow/defining.md
index bba29825..7bee711f 100644
--- a/guide/blueprints/workflow/defining.md
+++ b/guide/blueprints/workflow/defining.md
@@ -92,6 +92,9 @@ The config to define the sensor feed is:
if on the local entity, or a map of `sensor` containing the name and
`entity` containing the entity or entity ID
where the sensor should be listened for, or if just a single local sensor,
that sensor name supplied as a string
* `period`: whether the feed should run periodically
+* `skip_initial_run`: by default sensors and policies will run when created
(if any `condition` is met);
+ this can be set `true` to prevent that,
+ ensuring it is only run after the initial `period` or when one of the
`triggers` fires
In addition to defining the `sensor` name, at least one of `triggers` or
`period` must be supplied.
The `steps` must also be defined, as per `workflow-effector` above,
diff --git a/guide/blueprints/workflow/settings.md
b/guide/blueprints/workflow/settings.md
index 2f76ff31..ab7af87c 100644
--- a/guide/blueprints/workflow/settings.md
+++ b/guide/blueprints/workflow/settings.md
@@ -10,7 +10,7 @@ Some of the common properties permitted on [steps](common.md)
also apply to work
including `condition`, `timeout`, and `on-error`.
This rest of this section describes the remaining properties for more advanced
use cases
-including mutex locking and resilient workflows with replay points, and some
tips on optimizing.
+including mutex locking and resilient workflows with replay points.
## Locks and Mutual Exclusion Behavior
@@ -309,10 +309,11 @@ complicated replay or retention needs.
* **`idempotent`**
* when defining a workflow, as `idempotent: <value>`
- * **`all`**: means that all external steps in this workflow will be
resumable unless explicitly declared otherwise (
- by default, per below, external steps are not resumable); this includes
steps in explicit sub-workflows (where the
+ * **`all`**: means that all external steps in this workflow will be
resumable unless explicitly declared otherwise
+ (by default, per below, external steps are not resumable); this includes
steps in explicit sub-workflows (where the
workflow definition has a `workflow` with `steps`) but not sub-workflows
which are references (effectors or
registered workflow types)
+ * the empty string or null (the default): means normal idempotency
determination applies
* on a step as a key, as `idempotent: <value>`
* **`yes`**: the step is idempotent and the workflow can replay resuming
at this step if interrupted there
* **`no`**: the step is not idempotent and should not resumed at this
step; if interrupted there, replay resuming
@@ -476,25 +477,3 @@ on-error:
# finally restore default retention per parent or system, as details are now
stored on the entity
- workflow retention parent
```
-
-## Optimizing for Workflows
-
-Workflows can generate a huge amount of data which can impact memory usage,
persistence, and the UI.
-The REST API and UI do some filtering (e.g. in the body of the `internal`
sensors used by workflow),
-but when working with large `ssh` `output` and `http` `content` payloads, and
with `update-children`,
-performance can be dramatically improved by following these tips:
-
-* Optimize external calls to return the minimal amount of information needed
- * Use `jq` to filter when using `ssh` or `container` steps
- * Pass filter arguments to `http` endpoints that accept them
- * Loop over small page sizes (e.g. 20 records per cycle from `http`) using
`retry from` steps
-
-* Optimize the data which is stored
- * Override the `output` on `ssh` and `http` steps to remove unnecessary
objects;
- for example `http` returns several `content*` fields, and often just one
is needed.
- Simply settings `output: { content: ${content} }` will achieve this.
- * Set `retention: 1` or `retention: 0` on workflows that use a large amount
of information
- and can simply be replayed from the start; additionally `retention:
disabled` can be used
- to prevent any persistence (even for ongoing workflows), but only for
workflows that do
- not acquire any `lock`
-
diff --git a/guide/blueprints/workflow/steps/steps.yaml
b/guide/blueprints/workflow/steps/steps.yaml
index a62d7dd8..e84fba15 100644
--- a/guide/blueprints/workflow/steps/steps.yaml
+++ b/guide/blueprints/workflow/steps/steps.yaml
@@ -43,21 +43,16 @@
- name: transform
summary: Applies a transformation to a variable or expression
- shorthand: '`transform [TYPE] [ "value" ] VARIABLE_NAME [ = VALUE ] |
TRANSFORM`'
- input: |
- * `variable`: either a string, being the workflow variable name, or a
map, containing the `name` and optionally the `type`;
- if `value` is supplied, this variable will be set to the result of
all transforms and then coercion to any indicated type,
- e.g. to force conversion to an integer or to a bean registered type;
- if `value` is not supplied, the name is treated as a variable name
to resolve and coerce to any indicated type
- (i.e. wrapping the name in `${...}`; this is suppressed if the type
is the special keyword `value`, and `name` is resolved as a normal expression)
- and then used for the transform with the result being returned;
- `name` here can be of the form `x.key` where `x` is an existing map
variable, to user or set a specific `key` within it
- * `value_is_initial`: a boolean, implied in shorthand by the word
"value", means to treat the variable name as a value rather than a variable
name,
- evaluating it as a normal expression rather than wraping it in
`${...}`; this cannot be used it a `value` is supplied
- * `value`: the value to set, with some limited evaluation prior to
transforms as described [here](../variables.html);
- if not supplied, the `variable` is evaluated per the above and used
as the input for the transform
+ shorthand: '`transform [TYPE] [ VALUE | "value" VALUE | "variable"
VARIABLE_NAME | VARIABLE_NAME "=" VALUE ] "|" TRANSFORM`'
+ input: |
+ * `variable`: either a string, being the workflow variable name, or a
map, containing a `name` and/or a `type`;
+ if a variable name is supplied, it is set as the result of the
transform,
+ and if `value` is not supplied, its initial value is used as the
input to the transform (update in place)
+ * `value`: the value to start with; if omitted a `variable` is
required and its value used as the starting value;
+ where the value might be confused with a variable name it must be
explicitly offset with the keyword `"value"`;
+ more information is [here](../variables.html)
* `transform`: a string indicating a transform, or multiple transforms
separated by `|`, where a transform can be
- * `trim` to remove leading and trailing whitespace on strings, null
values from lists or sets, and any entry with a null key or null value in a map
+ * `trim` to remove leading and trailing whitespace on strings, null
and empty string values from lists or sets, and any entry with a null key or
null value in a map
* `replace MODE PATTERN REPLACEMENT` to replace a pattern in a
string with a replacement, supporting mode `regex`, `glob`, or `literal`
* `merge [list|set|map] [deep] [wait] [lax]` to treat the words in
the value as expressions to be combined;
indicates the value will be a space-separated list of values, with
quotes significant, usually including `$(vars)`;
@@ -66,6 +61,8 @@
if `wait`, unavailable sensor values are blocked on before merging;
if `lax` then nulls, and if not waiting unavailable sensors, are
silently removed
* `prepend <item>` and `append <item>` to add `<item>` at the start
or end, respectively, when the input to the transform is a list or a string
+ * `join [<separator>]` to concatenate stringable items from a list
+ * `split [limit <limit>] [keep_delimiters] [literal|regex]
<delimiter>` to split a string around the given `<delimiter>`, optionally
including the delimiters or limiting the count
* `slice <start-index> <optional-end-index>` to take a list and
return the sublist; a negative index is taken from the end
* `remove <item-or-index>` to remove an entry given a key (for a
map, ignoring if not found) or an index (for a list, negative index taken from
the end, failing if out of bounds)
* `wait` to wait on values (such as
`${entity.attributeWhenReady...}`); must precede any expression that has to
resolve values, such as `trim`)
@@ -83,6 +80,8 @@
* `to_string`, `to_upper_case`, and `to_lower_case` are accepted for
strings
* `resolve_expression` to trigger a re-resolution of the value being
transformed, eg if it has nested variable references that need resolution or
has been explicitly prepended and appended with `${` and `}`;
this is not done immediately but on the next step (or at the end),
so the value can be piped to `wait` if desired
+ * `get [<modifier>]` to get the unwrapped value of a supplier (if no
arguments) or get a specific indexed value or modifier sequence,
+ such as `get 0` or `get [0]` to get the first element of a list,
or `get .key.subkey[0]` to take an element `key` in a map, an element `subkey`
in the resulting map, and the first element of that list
* `set VAR` to set the workflow variable `VAR` to the the value at
that point in the transformation
* `return` to return the result of the transformation (not
compatible with supplying a `value` to set in a variable)
* any other word is looked up as a registered type of type
`org.apache.brooklyn.core.workflow.steps.transform.WorkflowTransform` (or
`WorkflowTransformWithContext` to get the context or arguments)
@@ -142,6 +141,7 @@
input: |
* `message`: a string to report in the exception
* `rethrow`: whether to include any error in scope (if being used
within an `on-error` step)
+ * `value`: on optional value that can be included in the failure, and
for callers to inspect additional context
output: _none_ (throws exception)
- name: retry
@@ -292,6 +292,21 @@
* `content_json`: the content, parsed as JSON if possible to return a
map, list, string, or primitive (null if not valid json)
* `duration`: how long the request took
+ - name: shell
+ summary: Runs a command using the local system shell
+ shorthand: '`shell COMMAND`'
+ input: |
+ * `command`: the command to run
+ * `env`: a map of string keys with values whose JSON is taken and
passed to the command be executed
+ * `exit_code`: the word `any`, a number, or a predicate DSL expression
(e.g. `less-than: 32`)
+ * `output_max_size`: by default output from commands is limited to
100k, truncating to keep the end; this can be increased or decreased,
+ or disabled with `-1` (assuming Apache Brooklyn has sufficient
memory to hold the data)
+ * `interpolation_mode` and `interpolation_errors`: as per `let` and
`load`, with defaults `full` and `ignore` so that applicable values are
resolved and others deferred
+ output: |
+ * `stdout`
+ * `stderr`
+ * `exit_code`
+
- name: ssh
summary: Runs a command over ssh
shorthand: '`ssh COMMAND`'
diff --git a/guide/blueprints/workflow/tips.md
b/guide/blueprints/workflow/tips.md
new file mode 100644
index 00000000..611956ce
--- /dev/null
+++ b/guide/blueprints/workflow/tips.md
@@ -0,0 +1,72 @@
+---
+title: Tips and Tricks
+layout: website-normal
+---
+
+## Filtering Lists
+
+There are many `transform` filters available, but none will filter lists.
+Removing elements from a list is easily be done by using `foreach`` with a
`condition`,
+returning elements that meet the condition.
+
+For example, to filter out non-empty strings from a list:
+
+```
+- let list_to_filter = [ "word1", "", "word2" ]
+- step: foreach item in ${list_to_filter}
+ condition:
+ size: { greater-than: 0 }
+ steps:
+ - return ${item}
+```
+
+The output from the `foreach` step is the list of results,
+so this results in the filtered list `["word1", "word2"]`.
+
+(This condition uses `size` to find the length of the string.
+The `condition: { not: { equals: "" } }` could just as well be used,
+or using the fact that `equals` can be made implicit, simply
+`condition: { not: "" }`.)
+
+Here is a more complicated example which filters comma-separated words
+to return known fruits and proper names:
+
+```
+- let requested_foods = "apple, banana, Nutella, invalid"
+- transform value ${requested_foods} | split regex \S*,\S* | trim
+- let list known_fruits = [ "apple", "orange", "banana" ]
+- step: foreach item in ${output}
+ condition:
+ any:
+ - regex: [A-Z].* # match proper name
+ - target: ${known_fruits} # match known fruits
+ contains: ${item}
+ steps:
+ - return ${item}
+```
+
+The above will return the list of `apple`, `banana`, and `Nutella`, dropping
`invalid`.
+
+
+
+## Optimizing for Workflows
+
+Workflows can generate a huge amount of data which can impact memory usage,
persistence, and the UI.
+The REST API and UI do some filtering (e.g. in the body of the `internal`
sensors used by workflow),
+but when working with large `ssh` `output` and `http` `content` payloads, and
with `update-children`,
+performance can be dramatically improved by following these tips:
+
+* Optimize external calls to return the minimal amount of information needed
+ * Use `jq` to filter when using `ssh` or `container` steps
+ * Pass filter arguments to `http` endpoints that accept them
+ * Loop over small page sizes (e.g. 20 records per cycle from `http`) using
`retry from` steps
+
+* Optimize the data which is stored
+ * Override the `output` on `ssh` and `http` steps to remove unnecessary
objects;
+ for example `http` returns several `content*` fields, and often just one
is needed.
+ Simply settings `output: { content: ${content} }` will achieve this.
+ * Set `retention: 1` or `retention: 0` on workflows that use a large amount
of information
+ and can simply be replayed from the start; additionally `retention:
disabled` can be used
+ to prevent any persistence (even for ongoing workflows), but only for
workflows that do
+ not acquire any `lock`
+
diff --git a/guide/ops/configuration/brooklyn_cfg.md
b/guide/ops/configuration/brooklyn_cfg.md
index 7b22351e..0000af1f 100644
--- a/guide/ops/configuration/brooklyn_cfg.md
+++ b/guide/ops/configuration/brooklyn_cfg.md
@@ -187,10 +187,10 @@ brooklyn.entitlements.global=<class>
The default entitlement manager is one which responds to per-user entitlement
rules,
and understands:
-* `root`: full access, including to the Groovy console
-* `poweruser`: full access, excluding to the Groovy console
-* `user`: access to everything but actions that affect the server itself.
Such actions include the
- Groovy console, stopping the server and retrieving management context
configuration
+* `root`: full access, including local scripts and the Groovy console
+* `poweruser`: full access apart from local shell scripts and Groovy scripts
+* `user`: access to everything but actions that affect the server itself.
Such actions include scripts,
+ stopping the server and retrieving management context configuration
* `blueprintAuthor`: same as user but cannot install bundles containing jar
or class files
* `readonly`: read-only access to almost all information
* `minimal`: access only to server stats, for use by monitoring systems
@@ -268,9 +268,16 @@ brooklyn.webconsole.security.login.form=brooklyn-ui-login
## SSH and Script Defaults
-Default values for SSH and script execution behaviour can be set in this file
+Default values for SSH connection and script execution behaviour can be set in
this file
using the prefix `brooklyn.ssh.config.`, as described in
[Locations](/guide/locations#os-setup).
+Local shell access via the `shell` workflow step, available only to users with
`root`-level entitlement,
+can be disabled altogether using the following setting:
+
+```
+brooklyn.security.shell.workflow_step.disabled=true
+```
+
## Certificate Validation