Qorus Integration Engine® Enterprise Edition 6.0.27_prod
Loading...
Searching...
No Matches
Finite State Machines / Flow Designer

Table of Contents

Back to the Developer's Guide Table of Contents

Overview of Finite State Machines / Flow Designer

All Qorus integration objects are described by YAML metadata produced by our IDE, which is available as a free (as in free of charge and also open source) extension to Microsoft Visual Studio Code, a multi-platform editor from Microsoft. The Qorus extension is called Qorus Developer Tools and can be installed directly from Visual Studio Code.

Qorus's Flow Designer creates executable configurations called finite state machines that allow arbitrary logic to be configured and deployed by connecting integration objects, supporting no-code solutions when existing building blocks are sufficient to cover the implementation requirements.

Note
  • Finite state machines can be defined for workflow steps, service methods, or jobs; if any finite state machine is defined for a trigger, then any code also defined for that action is ignored, and only the finite state machine is executed.
  • Finite state machines are executed entirely on the server side based on their configuration; this differs from class connections, which are executed based on code generated directly in the IDE.
Flow Designer Example

Finite state machines are made up of a set of states connected by state transitions which determine the flow of execution (and state data, for states that produce and accept data) and also control error handling.

Data Processing in Finite State Machines

Finite state machines can accept input data and produce output data as well; any input data submitted to the finite state machine when it is executed (either implicitly, such as when triggered from a service method call, other interface action, or event), is passed through the execution of the finite state machine; each state can accept or ignore its input data, and the data output by each state can be accepted or ignored by any states connected through transitions.

Finite State Machine Input Data

When editing config items in finite machine states, the input data passed to the state from the previous state can be referenced as $local:input; for example to get the account-id key from local input, you can use:

$local:{input.account-id} 

Note the following example using input data in the argument of an API call state; the same approach can also be used in config items and other arguments in other state types.

Referencing Local Input Data in an FSM State
See also
Config Item / Building Block Template Substitution Strings for more information about accessing contextual data with template strings

Finite State Machine Service Method Call Input Data

When a finite state machine is associated with a service method, the input data is made up of the arguments to the method call.

If there is only one argument to the method, the finite state machine input data is that single argument.

If there is more than one argument, the input data to the finite state machine is the entire list of method arguments.

Example 1
Consider the following method:
# Python
def method(self, info: dict, key: str) -> None:
...
// Java
void method(Hash info, String key) {
}
# Qore
method(hash<auto> info, string key) {
}
In this case, info will be accessible as $local:input[0], and key as $local:input[1] in the first state. Globally in the finite state machine, info will be accessible as $fsminput:*[0], and key as $fsminput:*[1].

Finite State Machine Step Method Input Data

When a finite state machine is associated with a step method, the input data depends on the method arguments. Generally, any method taking a single argument will have that single argument as the input data directly. Methods taking more than one argument will have the argument list as the input data. Methods taking no arguments will have no input data.

Finite State Machine Input Data for Array Step Primary Methods

Example Primary Array Step Method Input Data
The signature for array step prumary methods (all step types) is as follows (signature provided for reference, when a finite state machine is configured to run for the given step method, all code implemented for the step method is ignored and only the finite state machine is executed):
# Python
def primary(self, array_arg: Any) -> None:
...
// Java
void primary(Object array_arg) {
// ...
}
# Qore
primary(auto array_arg) {
# ...
}
In this case the array argument passed to the primary step method will be accessible as $local:input in the first state. Globally in the finite state machine, the array argument passed to the primary step method will be accessible as $fsminput:*.
See also
Primary Step Code

Finite State Machine Input Data for Array Step Validation Methods

Example Array Step Validation Method Input Data
The signature for async validation methods is as follows (signature provided for reference, when a finite state machine is configured to run for the given step method, all code implemented for the step method is ignored and only the finite state machine is executed):
# Python
def validation(self, array_arg: Any) -> str:
...
// Java
String validation(Object array_arg) {
// ...
}
# Qore
string validation(auto array_arg) {
# ...
}
In this case the array argument passed to the validation method will be accessible as $local:input in the first state. Globally in the finite state machine, the array argument passed to the validation method will be accessible as $fsminput:*.
See also
Validation Method

Finite State Machine Input Data for Async Step Validation Methods

Example Async Validation Method Input Data
The signature for async validation methods is as follows (signature provided for reference, when a finite state machine is configured to run for the given step method, all code implemented for the step method is ignored and only the finite state machine is executed):
# Python
def validation(self, key: Optional[str]) -> str:
...
// Java
String validation(String key) {
// ...
}
# Qore
string validation(*string key) {
# ...
}
In this case the async key passed to the validation method (if available) will be accessible as $local:input in the first state. Globally in the finite state machine, the async key passed to the validation method will be accessible as $fsminput:*.
See also
Validation Method

Finite State Machine Input Data for Async Array Step Validation Methods

Example Async Array Step Validation Method Input Data
The signature for async array step validation methods is as follows (signature provided for reference, when a finite state machine is configured to run for the given step method, all code implemented for the step method is ignored and only the finite state machine is executed):
# Python
def validation(self, key: Optional[str], array_arg: Any) -> str:
...
// Java
String validation(String key, Object array_arg) {
// ...
}
# Qore
string validation(*string key, auto array_arg) {
# ...
}
In this case the async key passed to the validation method (if available) will be accessible as $local:input[0] and the array argument as $local:input[1] in the first state. Globally in the finite state machine, the async key passed to the validation method (if available) will be accessible as $fsminput:*[0] and the array argument as $fsminput:*[1].
See also
Validation Method

Finite State Machine Input Data for Async Backend Step Validation Methods

Example Async Backend Method Input Data
The signature for async backend methods is as follows (signature provided for reference, when a finite state machine is configured to run for the given step method, all code implemented for the step method is ignored and only the finite state machine is executed):
# Python
def end(self, data: dict) -> None:
...
// Java
void end(Hash data) {
// ...
}
# Qore
end(hash<auto> data) {
# ...
}
In this case the hash passed to the backend method will be accessible as $local:input in the first state. Globally in the finite state machine, the hash passed to the backend method will be accessible as $fsminput:*.
See also
Asynchronous Back-End Code

Finite State Machine Input Data for Async Array Backend Step Validation Methods

Example Async Array Backend Method Input Data
The signature for async array backend methods is as follows (signature provided for reference, when a finite state machine is configured to run for the given step method, all code implemented for the step method is ignored and only the finite state machine is executed):
# Python
def end(self, data: dict, array_arg: Any) -> None:
...
// Java
void end(Hash data, Object array_arg) {
// ...
}
# Qore
end(hash<auto> data, auto array_arg) {
# ...
}
In this case the hash passed to the backend method will be accessible as $local:input[0] and the array argument as $local:input[1] in the first state. Globally in the finite state machine, hash passed to the backend method will be accessible as $fsminput:*[0] and the array argument as $fsminput:*[1].
See also
Asynchronous Back-End Code

Finite State Machine Variables

Local and global variables can be declared in a finite state machine flow, and in some cases read-only automatic variables are created depending on the context.

Declaring variables in a finite state machine allows the user to restrict values assigned to the variable to values of a certain type. If the type is declared as a DataProvider, then variable action states can also be created from the variable that allow actions to be executed on a persistent object that often represents a connection to a remote server or resource.

In addition, DataProviders that support transaction management can have transaction management actions performed on them as well, such as beginning, committing, or rolling back transactions.

Finite State Machine Automatic Variables

Automatic variables are created by the IDE when an FSM or block state is created in a context that implies a DataProvider variable.

There are two such cases:

Automatic variables that represent DataProvider object can then be used in FSM variable action states to perform actions on the objects.

Automatic Variables in FSMs

Finite State Machine States

Each state can be one of the following types:

Note
A mapper can also be considered a single-element data pipeline, because mappers can also be elements of data pipelines.

Finite State Machine Class Connector States

A class connector state executes a class connector for the given class. The state's input data is the class connector input data, and the state's output data is the connector's output data.

The class's config items can be configured in the state as well.

FSM Connector State

Finite State Machine Data Pipeline States

A data pipeline state is a state that executes a data pipeline. The input data to the state is the input data for the data pipeline.

Finite state machine data pipeline states do not have any output data, as pipelines have no output data.

Data pipelines do not have output data, because they are not necessarily linear; they can have any number of parallel queues, in which case there is no single final pipeline element; pipeline elements do not have output data but rather enqueue data for further processing, and in typical use cases the final data pipeline processor elements in a queue do not enqueu any data for further processing but rather write data to an output location, and finally data pipelines are designed to process large volumes of data (including the output processing of the data), therefore a bulk output of massive amounts of data is impractical and does not feature in the design of data pipelines.

FSM Pipeline State

Finite State Machine Variable Action States

Variable action states are states created from Finite State Machine Variables defined as DataProvider objects.

They can execute actions depending on the capabilities of the underlying DataProvider.

Finite State Machine Transaction Actions

Transaction actions can be performed on DataProvider objects that support transaction management.

Supported Transaction Actions

Action Description
begin transaction Executes a AbstractDataProvider::beginTransaction() call on the object, starting a transaction on the object. After this call, the transaction must be committed or rolled back, or an exception will be raised when the thread exits or the local thread resource context is closed
commit Executes a AbstractDataProvider::commit() call on the object, committing the transaction
rollback Executes a AbstractDataProvider::rollback() call on the object, rolling back the transaction
See also
Finite State Machine Transaciton Block States

Finite State Machine API Call States

An API call state is a state in the flow where an API call is made to an accessible DataProvider supporting the request-response integration pattern in Qorus.

These can be accessed through DataProvider factories, a connection supporting a DataProvider, or a remote Qorus connection.

The input type of the API call state depends on the value of the Allow API Arguments switch. If this switch is set to True, then there is no input type, and the state is compatible with all previous states, as the input data is used only as local context (as $local:input) when resolving arguments given in the state itself, otherwise the input type of the state is the request type.

In all cases the output type is the response type.

When the state is executed, the API is called using the argument data, either from input data (if Allow API Arguments is False) or from data given in the API call state itself (if Allow API Arguments is True) to form the request, and the response is returned as the output data of the state.

The following is an example API call state:

API Call State Example

Qorus APIs in API Call States

Qorus exports many convenient APIs through the qorus-api DataProvider factory that can be used in Finite State Machine.

The following is a table listing the available APIs.

Note
Each API should be self-documenting, as they are introspected with documentation about each API and also about each argument.

Qorus APIs in the qorus-api DataProvider Factory

API Path Description
factory/qorus-api/data-provider/create Executes a "create record" action in a record-based DataProvider; also supports upserting / merging in supported DataProvider
factory/qorus-api/data-provider/delete Executes a "delete record" action in a record-based DataProvider
factory/qorus-api/data-provider/do-request Executes a request-response API call in an API-based DataProvider
factory/qorus-api/data-provider/search Executes a record search action in a record-based DataProvider
factory/qorus-api/data-provider/search-bulk-iterator Returns a bulk record iterator object suitable for input to a data pipeline for record-based DataProviders
factory/qorus-api/data-provider/update Executes a "record update" action in a record-based DataProvider
factory/qorus-api/jobs/disable Disables a job
factory/qorus-api/jobs/enable Enables a job
factory/qorus-api/jobs/get-job-result Returns the result info for a job
factory/qorus-api/jobs/info Returns metadata and status information for a job
factory/qorus-api/jobs/reset Resets a job
factory/qorus-api/jobs/run Runs a job and returns the result
factory/qorus-api/jobs/set-active Activates a job
factory/qorus-api/jobs/set-inactive Deactivates a job
factory/qorus-api/jobs/list Provides DataProvider children representing all Qorus jobs
factory/qorus-api/jobs/list/<job-name-or-id>/enable Enables the given job
factory/qorus-api/jobs/list/<job-name-or-id>/disable Disables the given job
factory/qorus-api/jobs/list/<job-name-or-id>/info Returns metadata and status information for the given job
factory/qorus-api/jobs/list/<job-name-or-id>/reset Resets the given job
factory/qorus-api/jobs/list/<job-name-or-id>/run Runs the given job and returns the result
factory/qorus-api/jobs/list/<job-name-or-id>/set-active Activates the given job
factory/qorus-api/jobs/list/<job-name-or-id>/set-inactive Deactivates the given job
factory/qorus-api/services/call-method Calls a service method and returns the result
factory/qorus-api/services/disable Disables a service
factory/qorus-api/services/enable Enables a service
factory/qorus-api/services/info Returns metadata and status information for a service
factory/qorus-api/services/load Loads and initializes a service
factory/qorus-api/services/reset Resets a service
factory/qorus-api/services/set-autostart Sets the autostart value for a service
factory/qorus-api/services/unload Unloads a service
factory/qorus-api/services/list Provides DataProvider children representing all Qorus services
factory/qorus-api/services/list/<service-name-or-id>/call-method Calls a method in the given service and returns the result
factory/qorus-api/services/list/<service-name-or-id>/disable Disables the given service
factory/qorus-api/services/list/<service-name-or-id>/enable Enables the given service
factory/qorus-api/services/list/<service-name-or-id>/info Returns metadata and status information for the given service
factory/qorus-api/services/list/<service-name-or-id>/load Loads the given service
factory/qorus-api/services/list/<service-name-or-id>/reset Resets the given service
factory/qorus-api/services/list/<service-name-or-id>/set-autostart Sets the autostart value for the given service
factory/qorus-api/services/list/<service-name-or-id>/unload Unloads the given service
factory/qorus-api/util/break Executes a break action in a Finite State Machine loop
factory/qorus-api/util/continue Executes a continue action in a Finite State Machine loop
factory/qorus-api/util/get-data Returns data for onwards processing in subsequent Finite State Machine states
factory/qorus-api/util/log-message Logs a message in the current log file in a Finite State Machine
factory/qorus-api/util/post-async-queue Posts a value on an asynchronous queue for an asynchronous step
factory/qorus-api/util/post-sla-error Posts an error event metric on an SLA
factory/qorus-api/util/post-sla-success Posts a success event metric on an SLA
factory/qorus-api/util/post-sync-event Posts a workflow synchronization event to enable any workflow synchronization steps waiting on the event to continue processing
factory/qorus-api/util/rest-request Makes a REST request and returns the response
factory/qorus-api/util/throw-exception Throws an exception in a Finite State Machine
factory/qorus-api/util/workflow/bind-event Binds a workflow synchronization event to a workflow synchronization step
factory/qorus-api/util/workflow/bind-event-unposted Binds a workflow synchronization event to a workflow synchronization step only if the event is unposted
factory/qorus-api/util/workflow/bind-subworkflow Binds a subworkflow to a subworkflow step
factory/qorus-api/util/workflow/get-feedback Retrieves workflow feedback data from a subworkflow step in the parent workflow
factory/qorus-api/util/workflow/leave-feedback Leaves workflow feedback data from a subworkflow step for the parent workflow
factory/qorus-api/util/workflow/skip-async-step Skips binding an asynchronous queue entry to an asynchronous step
factory/qorus-api/util/workflow/skip-event Skips binding a workflow synchronization event to a workflow synchronization step
factory/qorus-api/util/workflow/skip-subworkflow Skips binding a subworkflow to a subworkflow step
factory/qorus-api/util/workflow/submit-async-key Binds a asynchronous queue key to an asynchronous step
factory/qorus-api/util/write-output Writes output data according to a template hash
factory/qorus-api/workflows/block-order Blocks a workflow order
factory/qorus-api/workflows/cancel-order Cancels a workflow order
factory/qorus-api/workflows/create-order Creates a workflow order
factory/qorus-api/workflows/exec-async Executes a workflow order in a synchronous workflow execution instance with an asynchronous call (the call returns immediately)
factory/qorus-api/workflows/exec-sync Executes a workflow order in a synchronous workflow execution instance with a synchronous call (the call returns when the workflow order has a final status)
factory/qorus-api/workflows/get-order-info Returns order information for a workflow order
factory/qorus-api/workflows/retry-order Retries a workflow order
factory/qorus-api/workflows/unblock-order Unblocks a workflow order and resets its previous status
factory/qorus-api/workflows/uncancel-order Uncancels a workflow order and resets its previous status
factory/qorus-api/workflows/disable Disables a workflow
factory/qorus-api/workflows/enable Enables a workflow
factory/qorus-api/workflows/info Returns metadata and status information for a workflow
factory/qorus-api/workflows/reset Resets a workflow
factory/qorus-api/workflows/set-autostart Sets the autostart value for a workflow
factory/qorus-api/workflows/list Provides DataProvider children representing all Qorus workflows
factory/qorus-api/workflows/list/<workflow-name-or-id>/disable Disables the given workflow
factory/qorus-api/workflows/list/<workflow-name-or-id>/enable Enables the given workflow
factory/qorus-api/workflows/list/<workflow-name-or-id>/exec-async Executes a workflow order for the given workflow in a synchronous workflow execution instance with an asynchronous call (the call returns immediately)
factory/qorus-api/workflows/list/<workflow-name-or-id>/exec-sync Executes a workflow order for the given workflow in a synchronous workflow execution instance with a synchronous call (the call returns when the workflow order has a final status)
factory/qorus-api/workflows/list/<workflow-name-or-id>/info Returns metadata and status information for the given workflow
factory/qorus-api/workflows/list/<workflow-name-or-id>/reset Resets the given workflow
factory/qorus-api/workflows/list/<workflow-name-or-id>/set-autostart Sets the autostart value for the given workflow

Qorus DataProvider API: Disable Job

Summary
Disables a job and returns information about the job and the action executed
Path to DataProvider API
factory/qorus-api/jobs/disable
Arguments
  • job: the job ID or name
Return Value
  • name (string): the job's name
  • version (string): the job's version
  • jobid (int): the job ID
  • info (string): a string giving the status of the operation

Qorus DataProvider API: Enable Job

Summary
Enables a job and returns information about the job and the action executed
Path to DataProvider API
factory/qorus-api/jobs/enable
Arguments
  • job: the job ID or name
Return Value
  • name (string): the job's name
  • version (string): the job's version
  • jobid (int): the job ID
  • info (string): a string giving the status of the operation

Qorus DataProvider API: Run Job

Summary
Runs a job and returns the result
Path to DataProvider API
factory/qorus-api/jobs/run
Arguments
  • job: the job ID or name
Return Value
  • job_instanceid: the unique ID of the result of running the job
  • status: The job status (either COMPLETE or ERROR)

Qorus DataProvider API: Run Implicit Job

Summary
Runs the job identified in the DataProvider path and returns the result
Path to DataProvider API
factory/qorus-api/jobs/list/job-name-or-id/run
Arguments
This API takes no arguments
Return Value
  • job_instanceid: the unique ID of the result of running the job
  • status: The job status (either COMPLETE or ERROR)

Qorus DataProvider API: Disable Service

Summary
Disables a service and returns information about the service and the action executed
Path to DataProvider API
factory/qorus-api/services/disable
Arguments
  • service: the service ID or name
Return Value
  • name (string): the service's name
  • version (string): the service's version
  • serviceid (int): the service ID
  • info (string): a string giving the status of the operation

Qorus DataProvider API: Enable Service

Summary
Enables a service and returns information about the service and the action executed
Path to DataProvider API
factory/qorus-api/services/enable
Arguments
  • service: the service ID or name
Return Value
  • name (string): the service's name
  • version (string): the joserviceb's version
  • serviceid (int): the service ID
  • info (string): a string giving the status of the operation

Qorus DataProvider API: Create Order

Path to DataProvider API
factory/qorus-api/workflow/create-order
Summary
Creates a workflow order for processing
Arguments
  • workflow: The workflow name, name:version, or workflow ID for the order to be created
  • staticdata: The initial static data for the order
  • dynamicdata: The initial dynamic data for the order
  • external_order_instanceid: An optional external ID for the workflow order
  • sensitive_data: A hash of sensitive data information for the workflow; this key can only be used when submitting the data over a secure (encrypted) connection; the keys are sensitive data key types, values are hashes keyed by sensitive data values, and the hash values have the following keys:
    • aliases: (optional list of strings) zero or more string aliases for the sensitive data
    • data: (hash) the sensitive data hash itself
    • meta: (optional hash) a hash of metadata for the sensitive data with the following recommended keys (recommended keys are not enforced by the API itself):
      • PURPOSE: free-form information about the purpose of the sensitive data
      • CATEGORIES: free-form information about the categories of sensitive data
      • RECIPIENTS: free-form information about the recipients or recipient catories of sensitive data
      • STORAGE: free-form information about the storage time or rules for sensitive data
  • status: The initial order status (default if not present READY); must be either READY or BLOCKED
  • parent_workflow_instanceid: A loosely-coupled workflow that will be marked as the parent of this workflow
  • priority: The order priority from 0 - 999; priority 0 is the highest; 999 is the lowest
  • scheduled: The earliest date and time the order can be processed; if this date is given as a future date/time value and a READY tatus is given, then the initial status of the workflow order data instance will be automatically changed to SCHEDULED
  • global_unique_key: A hash giving one or more unique order keys for the order (across all workflows regardless of workflowid, name, or version); keys are order key names and values are the string key values; if this key already exists for any order in the system, then the order creation will fail with a DUPLICATE-ORDER-KEY error; the hash key must be a valid order key, and the value is the unique key value; this value will also be created as an order key
  • workflow_specific_unique_key: A hash giving one or more unique order keys for the particular workflowid (which matches a unique name and workflow version); keys are order key names and values are the string key values; if any of the keys given already exists for an order with the target workflowid, then the order creation will fail with a DUPLICATE-ORDER-KEY error; the hash key must be a valid order key, and the value is the unique key value; this value will also be created as an order key
  • workflow_unique_key: A hash giving one or more unique order keys for the particular workflow by name only (across all workflows with the same name regardless of version); keys are order key names and values are the string key values; if this key already exists for a workflow order with the same name, then the order creation will fail with a DUPLICATE-ORDER-KEY error; the hash key must be a valid order key, and the value is the unique key value; this value will also be created as an order key
  • orderkeys: A hash of order keys for the order

Qorus DataProvider API: Disable Workflow

Summary
Disables a workflow and returns information about the workflow and the action executed
Path to DataProvider API
factory/qorus-api/workflow/disable
Arguments
  • workflow: the workflow ID or name
Return Value
  • name (string): the workflow's name
  • version (string): the workflow's version
  • workflowid (int): the workflow ID
  • info (string): a string giving the status of the operation

Qorus DataProvider API: Enable Workflow

Summary
Enables a workflow and returns information about the workflow and the action executed
Path to DataProvider API
factory/qorus-api/workflow/enable
Arguments
  • workflow: the workflow ID or name
Return Value
  • name (string): the workflow's name
  • version (string): the workflow's version
  • workflowid (int): the workflow ID
  • info (string): a string giving the status of the operation

Qorus DataProvider API: Break

Path to DataProvider API
factory/qorus-api/util/break
Summary
Executes a break action in a Finite State Machine loop
Arguments
This API takes no arguments

Qorus DataProvider API: Continue

Path to DataProvider API
factory/qorus-api/util/continue
Summary
Executes a continue action in a Finite State Machine loop
Arguments
This API takes no arguments

Qorus DataProvider API: Get Data

Path to DataProvider API
factory/qorus-api/util/get-data
Summary
Returns data for onwards processing in subsequent Finite State Machine states.

The argument can be of any type; as all API state arguments are subjected to automatic template substitution, this argument can also contain template strings.

Qorus DataProvider API: Post Async Queue

Path to DataProvider API
factory/qorus-api/util/post-async-queue
Summary
Posts a value to an asynchronous workflow step queue
Arguments
Details
Updates a pending entry in an asynchronous step queue with status WAITING to RECEIVED.

Data is stored serialized in YAML format, so that type information is preserved when passed to the step's asynchronous back-end code.

Qorus DataProvider API: Post SLA Error Event

Path to DataProvider API
factory/qorus-api/util/post-sla-error
Summary
Posts an error event metric on an SLA
Arguments
  • sla: the name of the SLA
  • value: The metric for the error event
  • err: the error code
  • desc: the error description

Qorus DataProvider API: Post SLA Success Event

Path to DataProvider API
factory/qorus-api/util/post-sla-success
Summary
Posts a success event metric on an SLA
Arguments
  • sla: the name of the SLA
  • value: The metric for the error event

Qorus DataProvider API: Post Synchronization Event

Path to DataProvider API
factory/qorus-api/util/post-sync-event
Summary
Posts a workflow synchronization event to enable any workflow synchronization steps waiting on the event to continue processing.
Arguments

Qorus DataProvider API: Bind Workflow Synchronization Event

Path to DataProvider API
factory/qorus-api/util/workflow/bind-event
Summary
Binds a workflow synchronization event to a workflow synchronization step.
Note
This API can only be called from a workflow synchronization step

Qorus DataProvider API: Bind Workflow Synchronization Event Unposted

Path to DataProvider API
factory/qorus-api/util/workflow/bind-event-unposted
Summary
Binds a workflow synchronization event to a workflow synchronization step but only if the event is still unposted.
Note
This API can only be called from a workflow synchronization step

Qorus DataProvider API: Bind Subworkflow

Path to DataProvider API
factory/qorus-api/util/workflow/bind-subworkflow
Summary
Binds a subworkflow to a subworkflow step
Arguments
  • workflow: The workflow name, name:version, or workflow ID for the order to be created
  • staticdata: The initial static data for the order
  • dynamicdata: The initial dynamic data for the order
  • external_order_instanceid: An optional external ID for the workflow order
  • sensitive_data: A hash of sensitive data information for the workflow; this key can only be used when submitting the data over a secure (encrypted) connection; the keys are sensitive data key types, values are hashes keyed by sensitive data values, and the hash values have the following keys:
    • aliases: (optional list of strings) zero or more string aliases for the sensitive data
    • data: (hash) the sensitive data hash itself
    • meta: (optional hash) a hash of metadata for the sensitive data with the following recommended keys (recommended keys are not enforced by the API itself):
      • PURPOSE: free-form information about the purpose of the sensitive data
      • CATEGORIES: free-form information about the categories of sensitive data
      • RECIPIENTS: free-form information about the recipients or recipient catories of sensitive data
      • STORAGE: free-form information about the storage time or rules for sensitive data
  • parent_workflow_instanceid: A loosely-coupled workflow that will be marked as the parent of this workflow
  • priority: The order priority from 0 - 999; priority 0 is the highest; 999 is the lowest
  • scheduled: The earliest date and time the order can be processed; if this date is given as a future date/time value and a READY tatus is given, then the initial status of the workflow order data instance will be automatically changed to SCHEDULED
  • global_unique_key: A hash giving one or more unique order keys for the order (across all workflows regardless of workflowid, name, or version); keys are order key names and values are the string key values; if this key already exists for any order in the system, then the order creation will fail with a DUPLICATE-ORDER-KEY error; the hash key must be a valid order key, and the value is the unique key value; this value will also be created as an order key
  • workflow_specific_unique_key: A hash giving one or more unique order keys for the particular workflowid (which matches a unique name and workflow version); keys are order key names and values are the string key values; if any of the keys given already exists for an order with the target workflowid, then the order creation will fail with a DUPLICATE-ORDER-KEY error; the hash key must be a valid order key, and the value is the unique key value; this value will also be created as an order key
  • workflow_unique_key: A hash giving one or more unique order keys for the particular workflow by name only (across all workflows with the same name regardless of version); keys are order key names and values are the string key values; if this key already exists for a workflow order with the same name, then the order creation will fail with a DUPLICATE-ORDER-KEY error; the hash key must be a valid order key, and the value is the unique key value; this value will also be created as an order key
  • orderkeys: A hash of order keys for the order
Details
This API is the alternative to calling Qorus DataProvider API: Skip Subworkflow
Note
This API can only be called from a subworkflow step

Qorus DataProvider API: Get Child Feedback

Path to DataProvider API
factory/qorus-api/util/workflow/get-feedback
Summary
This API retrieves workflow feedback data from a child order given the feedback key used by the child.
Arguments
Details
Internally this API is implemented with a call to WorkflowApi::getChildFeedback(), so its behavior is the same.

Child workflows can leave data to be retrieved by this API with Qorus DataProvider API: Leave Parent Feedback or with WorkflowApi::leaveParentFeedback().
Note
This API can only be called from an subworkflow step

Qorus DataProvider API: Leave Parent Feedback

Path to DataProvider API
factory/qorus-api/util/workflow/leave-feedback
Summary
This API leaves workflow feedback data in a child order for retrieval in the parent workflow.
Arguments
Details
Internally this API is implemented with a call to WorkflowApi::leaveParentFeedback(), so its behavior is the same.

The parent workflow can retrieve the data left by this API with Qorus DataProvider API: Get Child Feedback or with WorkflowApi::getChildFeedback().
Note
This API can only be called from a child order created from a subworkflow step in the parent.

Qorus DataProvider API: Skip Async Step

Path to DataProvider API
factory/qorus-api/util/workflow/skip-async-step
Summary
This API will cause the execution of an asynchronous step to be skipped.
Arguments
This API takes no arguments
Details
This API is the alternative to calling Qorus DataProvider API: Submit Workflow Async Key
Note
This API can only be called from an asynchronous step

Qorus DataProvider API: Skip Workflow Synchronization Event Step

Path to DataProvider API
factory/qorus-api/util/workflow/skip-event
Summary
Skips binding a workflow synchronization event to a workflow synchronization step
Arguments
This API takes no arguments
Note
This API can only be called from a workflow synchronization step

Qorus DataProvider API: Skip Subworkflow

Path to DataProvider API
factory/qorus-api/util/workflow/skip-subworkflow
Summary
Skips binding a subworkflow to a subworkflow step
Arguments
This API takes no arguments
Details
This API is the alternative to calling Qorus DataProvider API: Bind Subworkflow
Note
This API can only be called from a subworkflow step

Qorus DataProvider API: Submit Workflow Async Key

Path to DataProvider API
factory/qorus-api/util/workflow/submit-async-key
Summary
Binds a asynchronous queue key to an asynchronous step.
Arguments
  • key: the key for the asynchronous queue entry; must be unique in the queue; this key along with the queue name must be used later to update the queue to cause the step to go to a COMPLETE status.
Details
This API is the alternative to calling Qorus DataProvider API: Skip Async Step
Note
This API can only be called from an asynchronous step

Qorus DataProvider API: Write Output

Path to DataProvider API
factory/qorus-api/util/write-output
Summary
Writes output data to locations provided by the hash argument, which should be assigned a hash as follows.
Argument Format
key (data to write) ➜ location (output location)
YAML Argument Example
\$local:input: \$dynamic:account
Details
This above argument would result in FSM input data being stored in the account key of workflow dynamic data when executed in a workflow context.

Hash keys in the argument are subject to template substitution with UserApi::expandTemplatedValue() (where $local:input represents input data to the current state); hash values provide the output locations to store the values according to template substitution strings marked as writable (W).

Hash keys must be strings when passed to the internal API call, therefore any $ signs must be escaped.

Hash values must be strings representing output locations, therefore any $ signs must also be escaped.
Note
  • $local:input represents FSM state input data
  • Template values in API call arguments are automatically evaluated before being passed to the DataProvider; for this reason, all $ signs must be escaped with a backslash as in the above example, so they are evaluated by the Qorus API call itself and not during standard template evaluation of API call arguments by Qorus.
This API only works when called from a Qorus interface, as an interface context is needed for writing output data.

Finite State Machine Send Message States

A send message state sends a message with a message-based DataProvider.

This state has no input type, meaning that it's compatible with all other states on input. Input data is used only as local context (as $local:input) when resolving arguments given in the state itself.

Since sending DataProvider messages provides no output, the send message state also has no output.

Finite State Machine Single Record Search States

A single record search state uses the parameters configured in the state to execute a search for a single record in a record-based DataProvider, such a DB table or a platform that presents a table-like interface through the DataProvider API.

These can be accessed through DataProvider factories, a datasource connection, a connection supporting a DataProvider, or a remote Qorus connection.

Finite State Machine Single Record Search State

This state has no input type, meaning that it's compatible with all other states on input. Input data is used only as local context (as $local:input) when resolving arguments given in the state itself.

If the required_result option is True, then a search returning no record causes a SEARCH-SINGLE-RESULT-ERROR exception to be raised. In this case the output type is always the record type of the DataProvider.

In case a result is not required, the output type can also be no value.

Note
Use Finite State Machine Multiple Record Search States when the search can return more than one record

Finite State Machine Multiple Record Search States

A multiple record search state uses the parameters configured in the state to execute a search for a record set in a record-based DataProvider, such a DB table or a platform that presents a table-like interface through the DataProvider API.

These can be accessed through DataProvider factories, a datasource connection, a connection supporting a DataProvider, or a remote Qorus connection.

Finite State Machine Multiple Record Search State

This state has no input type, meaning that it's compatible with all other states on input. Input data is used only as local context (as $local:input) when resolving arguments given in the state itself.

If the required_result option is True, then a search returning no records causes a SEARCH-RESULT-ERROR exception to be raised. In this case the output type is always the record type of the DataProvider.

In case a result is not required, the output type can also be no value.

Finite State Machine Record Update States

A record update state uses the parameters configured in the state to update records based on search criteria and update criteria; the updates are performed in the given record-based DataProvider, such a DB table or a platform that presents a table-like interface through the DataProvider API.

These can be accessed through DataProvider factories, a datasource connection, a connection supporting a DataProvider, or a remote Qorus connection.

Finite State Machine Record Update State

This state has no input type, meaning that it's compatible with all other states on input. Input data is used only as local context (as $local:input) when resolving arguments given in the state itself.

If the required_result option is True, then an update operation updating no records causes a UPDATE-RESULT-ERROR exception to be raised.

In all cases the output type of this state is a hash with a single key: records_affected, where the value is the number of rows updated by the operation.

Finite State Machine Record Delete States

A record delete state uses the parameters configured in the state to delete records based on search criteria; the deletes are performed in the given record-based DataProvider, such a DB table or a platform that presents a table-like interface through the DataProvider API.

These can be accessed through DataProvider factories, a datasource connection, a connection supporting a DataProvider, or a remote Qorus connection.

Finite State Machine Record Delete State

This state has no input type, meaning that it's compatible with all other states on input. Input data is used only as local context (as $local:input) when resolving arguments given in the state itself.

If the required_result option is True, then a delete operation deleting no records causes a DELETE-RESULT-ERROR exception to be raised.

In all cases the output type of this state is a hash with a single key: records_affected, where the value is the number of rows deleted by the operation.

Finite State Machine Record Create States

A record create state uses the parameters configured in the state to create records; new records are created in the given record-based DataProvider, such a DB table or a platform that presents a table-like interface through the DataProvider API.

These can be accessed through DataProvider factories, a datasource connection, a connection supporting a DataProvider, or a remote Qorus connection.

Finite State Machine Record Create State

This state has no input type, meaning that it's compatible with all other states on input. Input data is used only as local context (as $local:input) when resolving arguments given in the state itself.

In all cases the output type of this state is the record type; the output value is the list of records created.

Finite State Machine Block States

Block states support executing a group of states as a "block"; there are for, foreach, and while as well as transaction block states.

A type of "local variable" is implemented for blocks in the $var:{} Template expression; each block has its own copies of variables in this hash, also a type of "global variable" if implemented in the $transient:{} Template expression; see the previous links and Config Item / Building Block Template Substitution Strings for more information.

The output data for a block is the output data for the last execution of the block defined by the output data of the last state to be executed in the block.

Flow Control in Finite State Machine Block States

When executing finite state machine blocks, the block's flow can be controlled by the following special exceptions:

  • FSM-BREAK: if this exception is thrown, a break action is performed, and the flow will exit the current block being executed
  • FSM-CONTINUE: if this exception is thrown a continue action is performed, and the flow will start again from the initial state, if there is another loop to be made in the block, otherwise the flow exits the current block

These exception can also be thrown with the following API DataProviders:

See also

Finite State Machine For Block States

Finite state machine for blocks implement a loop driven by the following configuration:

  • condition: the condition expression; evaluated immediately before each iteration of the loop is executed; the loop stops executing when this expression evaluates to False
  • init: the initialization expression; the value of this expression will be stored in the location identifed by init_var; this expression is evaluated once at the start of the loop
  • init_var: a string value giving the field name in the $var: hash where the value of the init expression is stored
  • language: either qore or python, giving the language for expression evaluation
  • update: the update expression for the for loop; if present, it is evaluted after each iteration of the loop is executed and before the condition expression is evaluated for the next iteration

All expressions (init, condition, and update) are first substituted with a call to UserApi::expandTemplatedValue(). If the value returned is a string, then it is evaluated with the language defined by language. If the value is any other type, then that value is used as the value of the expression without further evaluation.

For more information on the boolean evaluation of the condition template expression, see Finite State Machine Boolean Evaluation.

Note
  • Both init and init_var must be present or both are ignored
  • Both update and update_var must be present or both are ignored
  • qore is the default for the expression evaluation language as it is fully multithreaded
See also
Config Item / Building Block Template Substitution Strings

Finite State Machine For State Data Processing

The output data for a for block is the output data for the last state executed in the block.

Finite State Machine Foreach Block States

Finite state machine foreach blocks implement a loop driven by a value or a list of values driven by the following configuration:

  • loop: This expression is evaluated once at the start of the foreach loop, and the value returned is used to execute the loop and determine the data submitted to the initial state(s) in the block. If the expression evaluates to a list, then the loop is executed with each element of list in turn as the data for the initial state(s) in the block. If the expression evaluates to a single value, then the foreach loop is executed once for that value. If the expression evaluates to no value, then foreach loop execution is skipped.
  • language: either qore or python, giving the language for expression evaluation

The loop expression is first substituted with a call to UserApi::expandTemplatedValue(). If the value returned is a string, then it is evaluated with the language defined by language. If the value is any other type, then that value is used as the value of the expression without further evaluation.

Note
qore is the default expression evaluation language as it is fully multithreaded

Finite State Machine Foreach State Data Processing

The output data for a foreach block is the output data for the last state executed in the block.

Finite State Machine While Block States

Finite state machine while blocks implement a loop driven by the following configuration:

  • condition: the condition expression; evaluated immediately before each iteration of the loop is executed; the loop stops executing when this expression evaluates to False
  • language: either qore or python, giving the language for expression evaluation

The condition expression is first substituted with a call to UserApi::expandTemplatedValue(). If the value returned is a string, then it is evaluated with the language defined by language. If the value is any other type, then that value is used as the value of the expression without further evaluation.

For more information on the boolean evaluation of the condition template expression, see Finite State Machine Boolean Evaluation.

Note
qore is the default for the expression evaluation language as it is fully multithreaded

Finite State Machine While State Data Processing

The output data for a while block is the output data for the last state executed in the block.

Finite State Machine Transaciton Block States

Finite state machine transaction block states implement a block that implies a transaction in a transaction-capable DataProvider. The transaction block requires a DataProvider as configuration that will be created as the automatic variable trans that can then be used for operations on the DataProvider in DataProvider action states, such as record-based operations.

Transaction block states imply a transaction; at the beginning of the block an implicit call to AbstractDataProvider::beginTransaction() is made.

If the block exits without any active exception, then AbstractDataProvider::commit() is called on the DataProvider object, committing the transaction implicitly, otherwise if there is an active exception when the block exits, AbstractDataProvider::rollback() is called on the DataProvider object, rolling back the transaction.

Transaction State Block in the IDE

Finite State Machine If States

The if state is a special state that has a condition and True and False transitions. The condition is a string expression that is first processed with UserApi::expandTemplatedValue(). If the result of this expression is a string, then it is interpreted as an expression in the given language (either qore or python).

The value is then converted to a bool, which then triggers the execution of either the True transition(s) or the False transition(s).

Transitions in if states cannot be further qualified with conditions on each transition.

For more information on the boolean evaluation of the condition template expression, see Finite State Machine Boolean Evaluation.

Finite State Machine If State Data Processing

Input data is passed through as-is to states transitioned through if states.

Finite State Machine State Transitions

State transitions determine the flow of execution in finite state machines. At the end of executing each state, transitions are evaluated and executed in order. Each state transition (if not a transition from an if state) can be configured with a condition, which if evaluated to True, causes the flow of execution to continue to the next state. If there is no condition associated with the transition, then the transition is executed unconditionally.

State transition conditions can be either a string expression or a class connector; when the condition is evaluated, the result is converted to a boolean value as described here which determines if the flow of execution continues to the next state or not.

Transition expressions are first parsed with UserApi::expandTemplatedValue(). If the result of this expression is a string, then it is interpreted as an expression in the given language (either qore or python).

In either case, the resulting value is converted to a bool to determine if the transition is followed or not.

For more information on the boolean evaluation of the transition condition template expression, see Finite State Machine Boolean Evaluation.

Finite State Machine State Error Transitions

State transitions can also be configured with a string error value; if an exception is thrown during state execution, the exception error string is compared to the string error value, and if it matches, then execution continues in the target state.

The error string is derived depending on the source language as follows:

  • Python: the full error class name (ex: builtins.ValueError)
  • Java: the full error class name (ex: java.lang.NullPointerException)
  • Qore: the error string code (ex: SOCKET-CONNECT-ERROR)
Note
An exact match to the actual exception class is made for Python and Java; no subclass comparisons are made

Finite State Machine Boolean Evaluation

Finite state machine boolean evaluation is driven by two elements of configuration:

  • condition: a condition template expression
  • language: the evaluation language if condition evaluates to a string

First, condition is evaluated with an internal call to UserApi::expandTemplatedValue().

If the resulting value is a string, then it is evaluated with the language specified by language.

If the resulting value is not a string, then it is evaluated per its data type according to the table below.

Example 1
In this example, the template is evaluated with a local input context with the following keys:
{
    intent_name: "i.400.userID-correct",
    project_id: "02724364-f352-46a2-9279-083989c53360",
    session_id: "769113b8-ee2a-4495-acf3-b12bf4709790",
    timestamp: 1635493630000,
    timestamp_str: "Fri Oct 29 09:47:10 CEST+0200",
    parameters: {
        p_inbound_user_id: "SJ3ZA",
        yes: "ja"
    }
}
The following template:
"$local:input.parameters.p_inbound_user_id".val() 
will be first subjected to template substitution, resulting in the following string:
"SJ3ZA".val() 
which will then be evaluated as a Qore expression, resulting in the result True.
See also
<string>::val()
Example 2
If on the other hand, the following template would be evaluated in the same context as in the previous example:
"$local:input.parameters.p_outbound_user_id".val() 
This results in the following string after template substitution:
"".val() 
(because the "parameters" hash has no "p_outbound_user_id" key) which will then be evaluated as a Qore expression, resulting in the result False.
See also
<string>::val()
Example 3
As an alternative to achieve the same results as in the first example, the following template string:
exists $qore-expr-value:{$local:input.parameters.p_inbound_user_id} 
will be first subjected to template substitution, resulting in the following string:
exists "SJ3ZA" 
which will then be evaluated as a Qore expression, resulting in the result True.
See also
Example 4
If on the other hand, the following template would be evaluated in the same context as in the first example:
exists $qore-expr-value:{$local:input.parameters.p_outbound_user_id} 
This results in the following string after template substitution:
exists NOTHING 
(because the "parameters" hash has no "p_outbound_user_id" key) which will then be evaluated as a Qore expression, resulting in the result False.
See also
Note
  • To prohibit evaluation of a template value that results in a string, enclose the template in quotes; ex: "$local:version"
  • qore is the default expression evaluation language as it is fully multithreaded

Once the template has been resolved, the value is processed according to its type as in the following table:

Boolean Evaluation per Data Type
Type Description
bool value taken literally
string True if non empty and not "0", False if empty or "0"
int, float, or number True if non zero, False if zero
hash, list, binary True if non-empty, False if empty
date True if not 1970-01-01Z or a zero duration, False if 1970-01-01Z or a zero duration
nothing, null False
See also
Config Item / Building Block Template Substitution Strings