Official Plugins (Kuzzle v2.x)
Workflows v1.x
2

This plugin is part of the Kuzzle Enterprise Plan. If you are interested, please contact us.

Workflows #

Workflows are documents written in a database. They correspond to the definition of a Workflow

Workflow documents contain 3 categories of information

  • metadata describing the Workflow
  • conditions of the Workflow execution
  • actions to be performed if the conditions are validated

workflow-schema

Example: Workflow document

Copied to clipboard!
{
  name: 'Cold Chain Workflow Notif',
  description: 'Create an alert when the cold chain has been broken',
  disabled: true,
  payloadPath: '.',
  trigger: {
    type: 'notification',
    collection: 'sensors',
    filter: {
      range: {
        temperature: {
          gt: 0
        }
      }
    }
  },
  predicates: [
    {
      name: 'check-weather'
    }
  ],
  actions: [
    {
      type: 'task',
      name: 'create-alert',
    },
    {
      type: 'api',
      request: {
        controller: 'email',
        action: 'sendColdChain',
      }
    }
  ]
}

Metadata #

Metadata are information about the Workflow:

  • name: Workflow name
  • description: Workflow description
  • disabled: Workflow status
  • payloadPath: Path to extract a sub-payload (see below to learn more)
Copied to clipboard!
{
  name: 'Cold Chain Workflow',
  description: 'Trigger an alert if the cold chain is broken',
  disabled: false,
  payloadPath: 'input.body',
  // ...
}

Conditions #

The execution conditions of a Workflow are divided into two parts:

  • trigger: definition of an action on which the Workflow will start its execution
  • predicates: additional external verification before executing actions

There are two types of triggers, event and notification, the first one is connected to the internal event system of Kuzzle and the second one to the real-time notification system.

Only internal events having a KuzzleRequest as first argument can be used as Workflow trigger.

Payload Extraction #

Each Workflow must define the payloadPath property to extract a payload from its context. This payload is extracted from the original KuzzleRequest (trigger of type event) or DocumentNotification (trigger of type notification) and can be used to match additional filters.

This payload will be referred to during the life-cycle of the Workflow, for example:

The path of the extracted payload is represented as a lodash path. It is possible to specify the path "." to use the whole Request or Notification as the Workflow payload.

Example: Use the document content from a document notification as extracted payload

See example
Copied to clipboard!
{
  // ...
  payloadPath: 'result._source',
  trigger: {
    type: 'notification',
    index: 'nyc-open-data',
    collection: 'sensors',
    filter: {
      // set of koncorde filters
    }
  },
  // ...
}

Here the payloadPath is "result._source" because the document content is inside this property of DocumentNotification.

Copied to clipboard!
{
  "index": "tir-open-data",
  "collection": "red-taxi",
  "controller": "document",
  "action": "create",
  "protocol": "http",
  "timestamp": 1497513122738,
  "volatile": null,
  "scope": "in",
  "node": "knode-nasty-author-4242",
  "result":{
    "_source": {                 // <= Extracted payload
      "some": "document content",
      "_kuzzle_info": {
        "author": "-1",
        "createdAt": 1497866996975
      }
    },
    "_id": "<document identifier>"
  },
  "room":"893e183fc7acceb5-7a90af8c8bdaac1b"
}

Event Trigger #

Workflows can be triggered when Kuzzle emits one of its internal events via the Event System.

The trigger.type property must be set to event and the trigger.event property must contain the name of a Kuzzle internal event (e.g. auth:beforeLogin)

Only internal events having a KuzzleRequest as first argument can be used as Workflow trigger.

It is possible to refine the trigger by using the following properties:

  • trigger.collection: a specific collection name
  • trigger.filter: a set of Koncorde Filters

Example: Event triggered when a user with a specific email is created

See example
Copied to clipboard!
{
  // ...
  payloadPath: 'input.body.content',
  trigger: {
    type: 'event',
    event: 'security:afterCreateUser',
    filter: {
      regexp: {
        email: '.*@kuzzle\.io$'
      }
    }
  },
  // ...
}

This Workflow will be triggered when a user is created with an email address ending with @kuzzle.io:

Copied to clipboard!
kourou security:createUser '{           
  content: {    
    profileIds: ["default"],
    email: "efsun@kuzzle.io",
  },                    
}'

The extracted payload will contain the user custom content and it will be matched with the Workflow trigger filters.

Notification Trigger #

Workflows can be triggered when Kuzzle emits a realtime notification.

The trigger.type property must be set to notification. The trigger.collection and trigger.filter properties must be set to define a subscription scope.

The subscription scope index will automatically be set to the index containing the Workflow engine.

The Workflow will be triggered whenever a notification matching the subscription scope is generated by Kuzzle.

As real-time notifications can be triggered from backend code, it is important to check that the Workflow cannot trigger itself to avoid infinite loops.

See also Develop with Workflows.

Example: Notification triggered when a sensor detects a break in the cold chain

See example
Copied to clipboard!
{
  // ...
  payloadPath: 'result._source',
  trigger: {
    type: 'notification',
    collection: 'sensors',
    filter: {
      range: {
        temperature: {
          gt: 0
        }
      }
    }
  },
  // ...
}

This Workflow will be triggered each time a document is written with a temperature property greater than 0 in the collection sensors of the tenant index.

Copied to clipboard!
kourou document:create <tenant-index> sensors '{                                                    
  temperature: 2,
}'

By default, the Workflow is only triggered whenever a document enters the subscription scope.

You can change this behavior by modifying the trigger.scope property. (Default value: in)

Predicates #

When it comes to decide whether to execute or not the actions of a Workflow, Koncorde filters can fall short since they don't allow to define complex, programmatic conditions. This is what Predicates are for.

Predicates allow the execution of custom code in order to validate or not the execution of a Workflow's actions. This code is completely customizable and can be a call to an external API for example.

The Workflow Plugin ships with a set of predefined Predicates that you can attach to your Workflows right away, but you can also develop your own custom Predicate.

Custom Predicates must registered within the application code.

See Developing Predicates to learn how to develop new predicates.

Additional arguments can be passed to a predicate with the predicates[].args property.

Example: Use a weather predicate that accepts a rain argument (e.g. to know whether to check the rain level on an external API)

See example
Copied to clipboard!
{
  predicates: [
    {
      name: 'weather-predicate',
      args: {
        rain: true
      }
    }
  ]
}

Actions #

Once the conditions of a Workflow are validated, the Workflow actions can be executed.

These actions are executed sequentially and all share the same execution context so it's possible to pass information between each action. (See also WorkflowContext)

Actions are defined in the actions array of the Workflow document.

There are 4 types of actions:

  • api: execute a Kuzzle API action
  • task: execute a Task
  • rule: execute a Rule
  • rule-group: execute a group of Rules

API Action #

This action type triggers a call to the Kuzzle API.

The actions[].type property must be api and the actions[].request property must contain a RequestPayload.

The request's body will be injected with additional information:

  • workflow.id: the ID of the document defining the Workflow
  • workflow.name: the name of the Workflow
  • workflow.description: the description of the Workflow
  • payload: the extracted payload

API actions will be executed with the rights of the Workflow updater or author.

Example: Define a API action to create a document

See example

If you define the following action:

Copied to clipboard!
{
  // [...]
  actions: [
    {
      type: 'api',
      request: {
        controller: 'document',
        action: 'create',
        index: 'tenant-index',
        collection: 'alerts'
      }
    }
  ]
  // [...]
}

Then the following request will be sent to Kuzzle:

Copied to clipboard!
{
  controller: 'document',
  action: 'create',
  index: 'tenant-index',
  collection: 'alerts',
  body: {
    // Triggered workflow informations
    workflow: {
      id: '<workflowId'>,
      name: '<workflow name'>,
      description: '<workflow description'>,
    },
    // Extracted payload
    payload: {
      // ...
    }
  }
}

Task Action #

Tasks allow the execution of custom code.

The actions[].type property must be task and the actions[].name property must contain the name of a registered task.

Tasks must be developed and registered within the application code.

See Developing Task to learn how to develop new tasks.

Additional arguments can be passed to a task with the actions[].args property.

Example: Trigger a task that creates a document and accepts an argument called cold-chain

See example
Copied to clipboard!
{
  actions: [
    {
      type: 'task',
      name: 'create-alert',
      args: {
        type: 'cold-chain'
      }
    }
  ]
}

Rule Action #

You should read the Rules guide to fully understand this part.

Rules allow to conditionnaly execute actions.

The actions[].type property must be set to rule and the actions[].name property must contain the ID of a rule.

Like Workflows, they are composed of conditions to fulfill, and actions to be executed if the conditions are met.

A rule condition is composed of

  • a set of koncorde filters that will be matched with the extracted payload.
  • an array of predicates to validate

If all conditions are met, then the rule actions are executed.

Rule Group Action #

You should read the Rules guide to fully understand this part.

Rule group action allow to execute several rules in the same action.

The actions[].type property must be rule-group and the actions[].name property must contain the name of a rule group.

Rule groups are defined with the group property of the rule document.

When a rule group action is executed, all rules within the specified group are loaded. For each rule, the conditions are tested and if they are valid then its actions are executed.

The rules are executed sequentially but in no particular order.