Click here to Skip to main content
14,539,262 members

Wexflow - How to build automation in the cloud

Rate this:
5.00 (1 vote)
Please Sign up or sign in to vote.
5.00 (1 vote)
22 May 2020MIT
An easy and fast way to build automation and workflows in the cloud.

Image 1

Introduction

Wexflow is an open-source and cross-platform workflow engine and automation platform. The goal of Wexflow is to automate recurring tasks. With the help of Wexflow, building automation and workflow processes become easy. Wexflow also helps in making the long-running processes straightforward. The communication between systems or applications becomes easy through this powerful workflow engine and automation platform.

Wexflow can be used as an orchestration engine, for creating approval flows on generic business objects such as documents, invoices, purchase orders, vacation requests and time sheets, for form submission approval processes, for reporting, for automatically uploading videos to YouTube, Vimeo or Instagram, for automatically sending emails, tweets and SMS messages, for connecting systems and applications via hot folders or RESTful services, for database administration and maintenance, for batch uploading files, for batch downloading files, for recording live video feeds, for transcoding audio and video files, for processing images, for encrypting and decrypting files, for synchronizing the content of local or remote folders, etc.

To find out more about Wexflow, you can read the following documentation.

This article covers:

  1. How to deploy Wexflow
  2. How to configure Wexflow
  3. The architecture of Wexflow
  4. How to build approval flows
  5. How to build sequential flows
  6. How to build flowchart flows
  7. How to create and deploy custom tasks

How to deploy Wexflow

Image 2

You can deploy Wexflow using Docker containers on Windows, Linux and macOS distributions.

Docker Hub

To deploy Wexflow using Docker containers on Linux, follow this walkthrough:

1. Pull aelassas/wexflow

$ docker pull aelassas/wexflow

2. Copy the backend, the configuration files and the configuration folders from the container to the current folder

$ docker cp wexflow:/opt/wexflow/Backend Backend
$ docker cp wexflow:/opt/wexflow/Wexflow.Server/appsettings.json appsettings.json
$ docker cp wexflow:/opt/wexflow/Wexflow Wexflow
$ docker cp wexflow:/opt/wexflow/WexflowTesting WexflowTesting

3. Create the following docker-compose.yml in the current folder

version: "3"
services:
  wexflow:
    image: aelassas/wexflow:latest
    ports:
      - 8000:8000
    volumes:
      - ./appsettings.json:/opt/wexflow/Wexflow.Server/appsettings.json
      - ./Wexflow:/opt/wexflow/Wexflow
      - ./WexflowTesting:/opt/wexflow/WexflowTesting

  wexflow-backend:
    image: danjellz/http-server
    ports:
          - 8011:8011
    volumes:
      - ./Backend:/public
    command:
      http-server --cors -p 8011

4. Run the following command

$ docker-compose up

Wait for it to initialize completely and visit http://localhost:8011, or http://host-ip:8011 to access Wexflow's backend. You can also visit http://localhost:8000, or http://host-ip:8000 to access Swagger UI.

Docker images

To deploy Wexflow using Docker containers on Windows and macOS distributions, you must build your own Docker images.

If you want to build your own Docker images, below are the two possible configurations for creating and building Docker images.

Dockerfile

You can create a Docker image of Wexflow Server without the backend through the instructions below. In this case, the backend should be hosted on a web server.

  1. Create a folder named wexflow-5.7
  2. Put the following Dockerfile in the folder wexflow-5.7
  3. Download the Linux source zip file of the version 5.7
  4. Extract it to a folder named wexflow-5.7-linux-netcore
  5. Put the extracted folder wexflow-5.7-linux-netcore in the folder wexflow-5.7
  6. Move to the folder wexflow-5.7 (The content of this folder is Dockerfile and the folder wexflow-5.7-linux-netcore)
  7. Run the following commands:
    $ docker build -t wexflow .
    $ docker run -i -t -p 8000:8000 wexflow:latest
  8. Wait for it to initialize completely and visit http://localhost:8000 or http://host-ip:8000 to access Swagger UI

The default credentials are:

Username: admin
Password: wexflow2018

Once logged in, you can change the password from the backend.

Below is a screenshot from Ubuntu 18.04 (docker build):

Image 3

Below is a screenshot from Ubuntu 18.04 (docker run):

Image 4

Docker Compose

You can start Wexflow Server and its backend through Docker Compose by following the instructions below.

  1. Create a folder named wexflow-5.7
  2. Put the following docker-compose.yml in the folder wexflow-5.7
  3. Download the Linux source zip file of the version 5.7
  4. Extract it to a folder named wexflow-5.7-linux-netcore
  5. Put the extracted folder wexflow-5.7-linux-netcore in the folder wexflow-5.7
  6. Move to the folder wexflow-5.7 (The content of this folder is docker-compose.yml and the folder wexflow-5.7-linux-netcore)
  7. Run the following command:
    $ docker-compose up
  8. Wait for it to initialize completely and visit http://localhost:8011 or http://host-ip:8011 to access the backend
  9. Wait for it to initialize completely and visit http://localhost:8000 or http://host-ip:8000 to access the Swagger UI

The default credentials are:

Username: admin
Password: wexflow2018

Once logged in, you can change the password from the backend.

Below is a screenshot from Ubuntu 18.04 (docker-compose up):

Image 5

Configuration

By default, Wexflow is using LiteDB database system but you can switch to MongoDB, RavenDB, PostgreSQL, SQL Server, MySQL, SQLite, Firebird, Oracle or MariaDB.

MongoDB

Image 6

To use MongoDB database system, proceed as follows:

1. Create the following docker-compose.yml in the current folder

version: "3"
services:
  mongo:
     image: mongo:latest
     ports:
       - 27017:27017

  wexflow:
    image: aelassas/wexflow:latest
    depends_on:
      - mongo
    ports:
      - 8000:8000
    volumes:
      - ./appsettings.json:/opt/wexflow/Wexflow.Server/appsettings.json
      - ./Wexflow:/opt/wexflow/Wexflow
      - ./WexflowTesting:/opt/wexflow/WexflowTesting

  wexflow-backend:
    image: danjellz/http-server
    ports:
          - 8011:8011
    volumes:
      - ./Backend:/public
    command:
      http-server --cors -p 8011

2. Edit ./Wexflow/Wexflow.xml configuration file as follows:

<?xml version="1.0" encoding="UTF-8" ?>
<Wexflow>
  <Setting name="workflowsFolder" value="/opt/wexflow/Wexflow/Workflows" />
  <Setting name="recordsFolder" value="/opt/wexflow/Wexflow/Records" />
  <Setting name="recordsHotFolder" value="/opt/wexflow/Wexflow/Records/_HotFolder" />
  <Setting name="tempFolder" value="/opt/wexflow/Wexflow/Temp" />
  <Setting name="tasksFolder" value="/opt/wexflow/Wexflow/Tasks" />
  <Setting name="approvalFolder" value="/opt/wexflow/Wexflow/Approval" />
  <Setting name="xsd" value="/opt/wexflow/Wexflow/Workflow.xsd" />
  <Setting name="tasksNamesFile" value="/opt/wexflow/Wexflow/TasksNames.json" />
  <Setting name="tasksSettingsFile" value="/opt/wexflow/Wexflow/TasksSettings.json" />
  <Setting name="globalVariablesFile" value="/opt/wexflow/Wexflow/GlobalVariables.xml" />
  <!-- MongoDB -->
  <Setting name="dbType" value="MongoDB" />
  <!-- SslProtocols: None|Ssl2|Ssl3|Tls|Default|Tls11|Tls12 -->
  <Setting name="connectionString" value="Database=wexflow_netcore;MongoUrl=mongodb://mongo:27017;EnabledSslProtocols=false;SslProtocols=None" />
</Wexflow>

3. Run the following command

$ docker-compose up

Wait for it to initialize completely and visit http://localhost:8011, or http://host-ip:8011 to access Wexflow's backend. You can also visit http://localhost:8000, or http://host-ip:8000 to access Swagger UI.

RavenDB

Image 7

To use ravenDB database system, proceed as follows:

1. Create the following docker-compose.yml in the current folder

version: "3"
services:
  ravendb:
     image: ravendb/ravendb
     ports:
       - 8080:8080

  wexflow:
    image: aelassas/wexflow:latest
    depends_on:
      - ravendb
    ports:
      - 8000:8000
    volumes:
      - ./appsettings.json:/opt/wexflow/Wexflow.Server/appsettings.json
      - ./Wexflow:/opt/wexflow/Wexflow
      - ./WexflowTesting:/opt/wexflow/WexflowTesting

  wexflow-backend:
    image: danjellz/http-server
    ports:
          - 8011:8011
    volumes:
      - ./Backend:/public
    command:
      http-server --cors -p 8011

2. Edit ./Wexflow/Wexflow.xml configuration file as follows:

<?xml version="1.0" encoding="UTF-8" ?>
<Wexflow>
  <Setting name="workflowsFolder" value="/opt/wexflow/Wexflow/Workflows" />
  <Setting name="recordsFolder" value="/opt/wexflow/Wexflow/Records" />
  <Setting name="recordsHotFolder" value="/opt/wexflow/Wexflow/Records/_HotFolder" />
  <Setting name="tempFolder" value="/opt/wexflow/Wexflow/Temp" />
  <Setting name="tasksFolder" value="/opt/wexflow/Wexflow/Tasks" />
  <Setting name="approvalFolder" value="/opt/wexflow/Wexflow/Approval" />
  <Setting name="xsd" value="/opt/wexflow/Wexflow/Workflow.xsd" />
  <Setting name="tasksNamesFile" value="/opt/wexflow/Wexflow/TasksNames.json" />
  <Setting name="tasksSettingsFile" value="/opt/wexflow/Wexflow/TasksSettings.json" />
  <Setting name="globalVariablesFile" value="/opt/wexflow/Wexflow/GlobalVariables.xml" />
  <!-- RavenDB  -->
  <Setting name="dbType" value="RavenDB" />
  <Setting name="connectionString" value="Database=wexflow_netcore;RavenUrl=http://ravendb:8080" /> 
</Wexflow>

3. Run the following command

$ docker-compose up

Wait for it to initialize completely and visit http://localhost:8011, or http://host-ip:8011 to access Wexflow's backend. You can also visit http://localhost:8000, or http://host-ip:8000 to access Swagger UI.

Other database systems

For other database systems, simply edit ./Wexflow/Wexflow.xml configuration file, set the desired database system in dbType setting and set the related connectionString setting. You can find out more about how to configure other database systems in the following documentation.

Multi-language support

Wexflow provides multi-language support. There are three languages for the moment (English, French and Danish). English is the default language but you can easily switch the language from the language drop-down on the top right of the backend's menu.

To add a new language, simply edit the JavaScript file ./Backend/js/language.js. You will need to provide a flag icon for the new language. Once, you downloaded the flag icon, simply place it in ./Backend/images/ folder. The size of the flag icon must be 24x24 pixels.

Here is a sample for adding the German language (Deutsch) for example:

const languageModule = (function () {
    "use strict";

    const codes = [
        { Name: "English", Code: "en", Icon: "images/en.png" },
        { Name: "Français", Code: "fr", Icon: "images/fr.png" },
	    { Name: "Deutsch", Code: "de", Icon: "images/de.png" }
    ];

    let languages = {};
    languages["en"] = {};
    languages["fr"] = {};
    languages["de"] = {};

    // en
    languages["en"]["language"] = "Language";
    // ...

    // fr
    languages["fr"]["language"] = "Langue";
    // ...

    // de
    languages["de"]["language"] = "Sprache";
    // ...
	
    return {
        codes: codes,
        languages: languages
    };
})();

Architecture

This section covers the general architecture of Wexflow and an introduction to Wexflow concepts in order to make you understand the platform and become familiar with this automation platform.

Image 8

Wexflow is composed of three main components. Wexflow server, Wexflow API and Wexflow database. Wexflow server, Wexflow API and Wexflow database are built using .NET Core. Wexflow also provides three main client-side components. A powerful backend built using JavaScript, an Android app and an iOS app for querying Wexflow server.

Since workflows are typically long running processes, they will need to be persisted to storage between tasks or activities. There are several persistence providers available. Wexflow provides LiteDB, MongoDB, RavenDB, PostgreSQL, SQL Server, MySQL, SQLite, FirebirdOracle and MariaDB persistence providers. LiteDB is the default persistence provider since it needs zero configuration but you can switch to the persistence provider of your choice during the deployment.

The backend allows you to search and filter among all your workflows, have real-time stats on your workflows, manage your workflows with ease, design your workflows with ease, and track your workflows with ease:

Image 9

Wexflow provides an Android app so you can manage your flows easily from your Android device:

Image 10

Wexflow provides an iOS app so you can manage your flows easily from your iOS device:

Image 11

You can create custom integration with any other SaaS product in the cloud through Wexflow API:

Image 12

In Wexflow, a worklow is a set of task or activities that are either launched sequentially, or through a flowchart flow or through an approval flow. A workflow can be created from the designer tab in the backend:

Image 13

The user can create a workflow from the diagram view by dragging & dropping tasks or activities from the left panel to the diagram view then by clicking on each task in order to configure its settings in the right panel.

A workflow can either be launched manually from the manager tab, or launched periodically or by defining a cron expression.

Wexflow makes use of Quartz.NET open-source job scheduling system that is used in large scale enterprise systems. Thus, Wexflow offers flexibility in planning workflows jobs such as cron workflows. Cron workflows are often more useful than manual or periodic workflows, if you need a job-firing schedule that recurs based on calendar-like notions, rather than on the exactly specified intervals.

To set up a manual workflow, simply select Trigger launch type in the right panel in the designer. To set up a periodic workflow, simply select Periodic launch type in the right panel in the designer and specify the period. To set up a cron workflow, simply select Cron launch type in the right panel in the designer and specify the cron expression.

By default, parallel execution of workflows is enabled, this means that if you kick off multiple instances of a same workflow at the same time, these instances are launched in parallel. To disable parallel execution and enable queueing, simple uncheck Enable parallel exectution checkbox in the right panel of the designer. If parallel exection is disabled, and if you kick off multiple instances of a same workflow at the same time, these instances are queued and each instance will wait until the instance before finishes its job.

A workflow executes a set of tasks or activities. Each task is a module which can be enabled, disabled or replaced. Wexflow provides 95 built-in tasks for different kind of jobs. There are file system tasks, network tasks, email tasks, SMS tasks, SQL tasks, reporting tasks, social media tasks, flowchart tasks, approval tasks, etc.

The execution flow of the tasks can be edited from the execution graph of the workflow. If a workflow does not have an execution graph, the tasks are launched sequentially one after the other. If a workflow has an execution graph, the flow described in it will be respected.

Below a sample execution graph from the graph view in the designer tab:

Image 14

The execution graph of a workflow can be edited either from the JSON definition or XML definition of a workflow.

The execution graph of a workflow can contain an If, a While or a Swich flowchart nodes. Each flowchart node takes as input a flowchart task and a set of tasks to run.

The execution graph can also contain workflow events. After a workflow finishes its job, its final result is either success, warning, error or rejected. If its final result is success, the OnSuccess event is triggered. If its final result is warning, the OnWarning event is triggered. If its final result is error, the OnError event is triggered. If the workflow is rejected, the OnRejected event is triggered. An event contains a set of tasks and/or flowchart nodes to run.

Workflows can be kicked off manually from the manager tab:

Image 15

The manager tab allows also to view the running instances of a workflow and allows to stop, approve or reject an instance.

Everything that happens in Wexflow is traced and logged. With Wexflow's logging system, you can track your workflows with ease and stay informed with real-time monitoring and email notifications.

Wexflow's logs are written in /opt/wexflow/Wexflow.Server/Wexflow.log. There is one log file per day. The old log files are saved in following format: Wexflow.logyyyyMMdd

Below is a sample of the log file Wexflow.log:

Image 16

Wexflow makes use of log4net, a tool that helps to output log statements to a variety of output targets. Thus, It is possible to configure Wexflow to send incident reports when an error occurs by using log4net.Appender.SmtpAppender in the configuration file /opt/wexflow/Wexflow.Server/log4net.config of Wexflow . Below is a sample configuration:

<appender name="SmtpAppender" type="log4net.Appender.SmtpAppender">
    <to value="foo@bar.com" />
    <from value="baz@bar.com" />
    <subject value="Some subject" />
    <smtpHost value="smtp.gmail.com" />
    <authentication value="Basic" />
    <port value="587" />
    <username value="gmail user name" />
    <password value="gmail password" />
    <bufferSize value="1" />
    <EnableSsl value="true"/>
    <lossy value="true" />
    <evaluator type="log4net.Core.LevelEvaluator">
        <threshold value="ERROR"/>
    </evaluator>
    <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%newline%date [%thread] %-5level %logger [%property{NDC}] - %message%newline%newline%newline" />
    </layout>
</appender>

Wexflow gives you a beautiful dashboard to view real-time statistics on your workflows. Indeed, the dashboard tab gives you real-time statistics on your workflows and will let you track your workflow server with ease and details. From the dashboard tab, you can also filter the workflow entries by a keyword or by date. You can also sort the workflow entries by date, by name, etc:

Image 17

When you click on an entry, you will get the logs of the corresponding entry in a popup as follows:

Image 18

The History tab in the backend will also let you track all your workflows and everything that happens on the workflow server. Indeed, from this tab you will have an overview of all the workflow instances executed on the workflow server. Furthermore, you can filter the entries by keywords or date. You can also sort the entries by date, by name, etc:

Image 19

When you click on an entry, you will get the logs of the corresponding entry in a popup:

Image 20

Approval flows

Wexflow allows to create approval flows on generic business objects such as documents, invoices, purchase orders, vacation requests, time sheets, etc. These generic business objects are called records.

Records

A record is a generic business object that includes the following informations:

Field Type
Id Identifier
Name Single line of text
Description Multiple lines of text
Approved Yes/No
Start date Date and time
End date Date and time
Comments Multiple lines of text
Manager comments Multiple lines of text
Created by Person
Created on Date and time
Modified by Person
Modified on Date and time
Assigned to Person
Assigned on Date and time
Approvers Persons
Versions Files

To create a new record, only the name field is required.

To create a new record, proceed as follows:

  1. Sign in to Wexflow
  2. Select Records tab
  3. Click on New record button
  4. Fill the informations about the record (only the name is required)
  5. Add a file to the record if necessary (you can drag & drop the file into the record's box or simply click on upload button)
  6. Click on Save

Once you click on Save, the record is created and can then be used in approval flows for approval processes.

Serial approval flows

To create a serial approval flow:

  1. Sign in to Wexflow
  2. Select Designer tab
  3. Click on New workflow button
  4. Fill the name and the launch type of the workflow (only the name and the launch type are required)
  5. Set the workflow type as Approval (The workflow will then show up in Approvals tab)
  6. Drag and drop ApproveRecord task into the diagram view
  7. Fill the settings of ApproveRecord task by clicking on the task in the workflow designer
  8. Finally, press Ctrl+S to save your serial approval flow

This serial approval flow launches an approval process on a record assigned to a user in Wexflow. You can add other specific tasks in the serial approval flow for example for processing the latest file version of the record, for digital signature, for sending emails, etc. Simply by dragging & dropping the desired tasks in the designer. You can also set events on the record. The following events are supported:

  • onApproved: Executes a set of tasks once the record is approved
  • onRejected: Executes a set of tasks once the record is rejected
  • onDueDateReached: Executes a set of tasks once the record's due date is reached
  • onReminderDateReached: Executes a set of tasks once the record's reminder date is reached
  • onDeleted: Executes a set of tasks once the record is deleted
  • onStopped: Executes a set of tasks once the approval workflow is stopped

To set an event simply, set the task ids in the event field comma separated (ex: 2, 3).

To kick off your serial approval flow:

  1. Select Approvals tab
  2. Select your flow and click on Start

To approve a serial workflow, select the approval job and click on Approve.

To reject a serial workflow, select the approval job and click on Reject.

To stop a serial workflow, select the approval job and click on Stop.

Once the approval workflow is started, the user assigned to the record receives a notification in Wexflow and by email.

The user assigned to the record can mark the notifications as read or unread, or delete them.

If the record's reminder date is reached, the user assigned to the record and the manager are notified.

If the record's due date is reached, the user assigned to the record and the manager are notified.

Once the approval flow is approved, the user assigned to the record receives a notification in Wexflow and by email.

If the approval flow is rejected, the user assigned to the record receives a notification in Wexflow and by email.

If the approval flow is stopped by the manager, the user assigned to the record receives a notification in Wexflow and by email.

If the record is modified or deleted by the manager, the user assigned to the record receives a notification in Wexflow and by email.

Here is a brief overview of an approval flow:

  1. Create a record (The manager can delete records. The user assigned to a record can modify the record by uploading new file versions and adding comments but he cannot delete the record he has not created. The user assigned to a record can only delete the records he created.).
  2. Create a workflow that takes as input the record and the user assigned to that record (A super-Admin or Admin user in Wexflow).
  3. When the manager (A Super-Admin user in Wexflow) kicks off an approval workflow, a notification is sent to the user assigned to the record saying that he was assigned to work on that record.
  4. Once the user assigned to the record modifies the record (by uploading a new file version of the record for example), a notification is sent to the manager saying that he have to check that record.
  5. Once the manager checks the record he can add comments and if so, a new notification is sent to the user assigned to the record.
  6. If the manager deletes the record, the user assigned to the record is notified.
  7. If the record's reminder date is reached, the user assigned to the record and the manager are notified.
  8. If the record's due date is reached, the user assigned to the record and the manager are notified.
  9. If the manager approves the record, a notification is sent to the user assigned to the record saying that the record was approved.
  10. If the manager rejects the record, a notification is sent to the user assigned to the record saying that the record was rejected.
  11. The approval can be stopped by the manager.

A non-manager user can also create records and approval flows but he cannot access the records he did not create and the approval flows he did not create. He can only edit the records he created or assigned to him. He cannot delete the records he did not create but he can delete the records he created. If a non-manager user modifies a record assigned to him, the manager of the record receives a notification and an email. If the manager modifies a record assigned to a user, the user assigned to the record receives a notification and an email.

Parallel approval flows

In a parallel approval flow, multiple persons are required to approve items such as documents, invoices, purchase orders, vacation requests, time sheets, etc. Each person's approval is independent of all other approvers.

It is possible to create parallel approval flows in Wexflow, by creating approval workflows and kicking them off in parallel.

Once the multiple approval workflows are started in parallel, the sales team and the HR team assigned to the record for example will receive a notification in Wexflow and by email in order to work on the record. If the record is modified, the manager will receive notifications in Wexflow and by email telling that the record was modified so that he can check and approve or reject the flow. If the manager modifies the record by adding new comments on the record for instance, the user assigned to the record will receive a notification in Wexflow and by email telling that the record was modified by the manager. If the manager approves, rejects or stops the approval workflow, the user assigned to the record will get notified in Wexflow and by email. If the record is deleted by the manager during the approval flow, the user assigned to the record will get notified in Wexflow and by email.

It is also possible to run extra tasks on the latest file version of the record by setting the events of ApproveRecord task onApproved, onRejected, onDeleted, onDueDateReached, onReminderDateReached and onStopped. If the record does not have files such as vacation requests for instance, it is also possible to kick off extra tasks by setting the events of ApproveRecord task such as loading and sending emails or digital signature or creating a task in Microsoft Tasks for instance.

Below is a sample parallel approval flow:

Image 21

In this sample two approval flows are started in parallel on the same record. Once the manager approves the first flow, the sales team will get a notification in Wexflow and by email. And once the manager approves the second flow, the HR team will get a notification in Wexflow and by email.

All must approve

These approval workflows are approval workflows that require everyone (all assigned approvers) to agree for a vacation request to be approved for instance, but any approver can reject the entire request.

This type of approval workflows is useful in an organization that requires a person's manager and the manager's manager, to both agree to a vacation request for it to be approved. However, either manager can decline the request without the other person's input.

To start this type of workflows in Wexflow, simply create multiple approval workflows on the same record then start the approval flows. Once all approvers approve the record, the record will be marked as approved and the list of approvers will be listed in the record's box as follows:

Image 22

If an approver rejects the record, the entire request is rejected and the record is not marked as approved. The user assigned to the record will receive a notification regarding the rejection of the record and the approver who rejected the record can be shown in the record's information box.

Once all approvers approve the record, all the approvers will receive a notification regarding the approval of the record.

Records hot folder

There is a hot folder in Wexflow for importing records from files.

The folder path of the hot folder can be configured from ./Wexflow/Wexflow.xml setting file through recordsHotFolder setting.

It is possible to enable or disable this hot folder. By default, it is enabled. To disable it, simply set the setting EnableRecordsHotFolder to false in appsettings.json configuration file.

Automated import flow

It is possible to set up automated import flows for records and start the approval flows automatically. To do so, you have to set up a workflow that watches for files in a certain hot folder and once the files arrive to that folder, the records are created and the approval flows are created too and started automatically.

You have a sample workflow for this type of workflows called Workflow_Approval_Import:

Image 23

This workflow watches the hot folder ./WexflowTesting/RecordsHotFolder and once the files arrives to that folder it creates the corresponding records and moves the files to records' repository. Finally, the approval flows are automatically created and started. These approval workflows assign the record to a user in Wexflow and start the approval flow on the corresponding records.

Enable email notifications

It is possible to enable or disable email notifications related to approval flows in Wexflow. By default, email notifications related to approval workflows are disabled. To enable them, simply set the setting EnableEmailNotifications to true in appsettings.json. If, you enable email notifications, you must also set Smtp.* settings in the same configuration settings file.

Digital signature

It is possible to enable digital signature such as DocuSign in an approval flows in Wexflow. For the moment, there isn't a built-in task for that purpose but the user can easily create his own digital signature task by creating a new custom task.

Microsoft Tasks

It is also possible to sync approval flows with Microsoft Tasks. For the moment, there isn't a built-in task for that purpose but the user can easily create his own synchronization task by creating a new custom task.

Sequential flows

A sequential flow executes a set of tasks or activities one by one. Each task does its job then the next one does its job until the last task is reached.

To create a sequential flow:

  1. Sign in to Wexflow
  2. Select Designer tab
  3. Click on New workflow button
  4. Fill the name and the launch type of the workflow (only the name and the launch type are required)
  5. Drag & drop the desired tasks from the left panel into the diagram view
  6. Fill the settings of each task by clicking on the task from the diagram view
  7. Finally, press Ctrl+S to save your sequential flow

To kick off your sequential flow:

  1. Select Manager tab
  2. Select your flow and click on Start

Below is a sample sequential flow:

Image 24

This simple flow starts by loading CSV files, then it transforms CSV files into XML files and finally it moves the resulted XML files to a dedicated folder.

You can see other sequential flows by clicking on Browse button in the designer tab, choosing a sequential flow and then double-clicking on the flow to open it in the designer.

You can view the execution graph of the sequential flow by clicking on Graph view from the designer tab.

You can also view or edit the JSON or XML definitions of the sequential flow by clicking on JSON or XML views from the designer tab.

Flowchart flows

A flowchart flow is a flow that contains at least one If, one While, or one Switch flowchart node in its execution graph.

To create a flowchart flow:

  1. Sign in to Wexflow
  2. Select Designer tab
  3. Click on New workflow button
  4. Fill the name and the launch type of the workflow (only the name and the launch type are required)
  5. Drag & drop the desired tasks from the left panel into the diagram view
  6. Fill the settings of each task by clicking on the task from the diagram view
  7. Switch to JSON or XML view and create the exection graph of the workflow
  8. You can see samples of the execution graph by opening the workflow Workflow_ExecutionGraph from the designer tab
  9. The execution graph must at least contain an If, a While or a Switch flowchart node
  10. Finally, press Ctrl+S to save your flowchart flow

To kick off your flowchart flow:

  1. Select Manager tab
  2. Select your flow and click on Start

Below is a sample flowchart flow:

Image 25

This simple flowchart flow starts by retieving the current day, then if it is Monday it executes the task 1, if it is Wednesday it executes the task 2 and finally for other days it executes the task 3.

Custom tasks

Custom tasks are a must in a workflow engine and allow systems and applications to interact.

To create a custom task MyTask for example you will need to proceed as follows:

  1. Create a .NET Core library project in Visual Studio that targets .NET Core 3.1 and name it Wexflow.Tasks.MyTask.
  2. Install Wexflow nuget package through nuget package manager:
    PM> Install-Package Wexflow
  3. Create a public class MyTask that implements the abstract class Wexflow.Core.Task.

Wexflow.Tasks.MyTask code should look like as follows:

using System.Xml.Linq;
using Wexflow.Core;

namespace Wexflow.Tasks.MyTask
{
    public class MyTask : Task
    {
        public MyTask(XElement xe, Workflow wf) : base(xe, wf)
        {
           //
           // Task settings go here
           //
        }

        public override TaskStatus Run()
        {    
           //
           // Task logic goes here
           //
           return new TaskStatus(Status.Success);
        }
    }
}

Each task returns a TaskStatus object when it finishes performing its job. TaskStatus is composed of the following elements:

public Status Status { get; set; }
public bool Condition { get; set; }
public string SwitchValue { get; set; }

The Status can be one of the followings:

public enum Status
{
  Success,
  Warning,
  Error
}

For example, if a task performs an opetation on a collection of files and if this operation succeeds for all the files then its Status should be Success. Otherwise, if this operation succeeds for some files and fails for others then its Status should be Warning. Otherwise, if this operation fails for all the files then its Status should be Error.

The Condition property is designed for flowchart tasks. In addition to the Status of the task, a flowchart task returns either true or false after performing its job.

The Condition property should always be set to false for sequential tasks.

The SwitchValue is designed to be used by Switch flowchart tasks. If you set a value in the SwitchValue property and use this task in a Switch flowchart node, the case corresponding to the value will be executed. Otherwise, if the Default case is set, it will be executed.

You can use the TaskStatus constructor that suits your needs.

To retrieve settings, you can use the following methods:

string settingValue = this.GetSetting("settingName");
string settingValue = this.GetSetting("settingName", "defaultValue");
string[] settingValues = this.GetSettings("settingName");

To select the files loaded by the running instance of a workflow through the selectFiles settings option, you can do it as follows:

FileInf[] files = this.SelectFiles();

To select entities loaded by the running instance of a workflow through the selectEntities settings option, you can do it as follows:

Entity[] entities = this.SelectEntities();

The Entity class could be very useful when working with custom tasks that manipulate objects from a database or Web Services for example.

To load a file within a task, you can do it as follows:

this.Files.Add(new FileInf(path, this.Id));

To load an entity within a task, you can do it as follows:

this.Entities.Add(myEntity);

Finally if you finished coding your custom task, compile the class library project and copy the assembly Wexflow.Tasks.MyTask.dll in ./Wexflow/Tasks.

Your custom task is then ready to be used.

That's it. That's all the things you need to know to start coding your own custom tasks.

Designer

To make your custom task MyTask appear in the designer tab, simply open the file ./Wexflow/TasksNames.json and add "MyTask" in it as follows:

[
  ...
  { "Name": "MyTask", "Description": "MyTask description."}
]

You must also add the settings by opening the file ./Wexflow/TasksSettings.json and adding your custom settings as follows:

{
  ...
  "MyTask": [{"Name": "settingName", "Required": true, "Type": "string", "List": [], "DefaultValue": ""}]
}

The setting type can be int, string, bool, list, password, user or record. If the setting is not required, you must specify a default value. If the setting type is list, you must specify the list items in "List" property (ex: ["ftp", "ftps"]).

That's it. MyTask will show up in the designer and when selected its settings will show up too.

Testing

To test the custom task, create a new workflow from the designer, drag & drop your custom task into the diagram view, click on your custom task, edit the settings of your custom task and finally press Ctrl+S to save your workflow. The workflow will then appear in the list of workflows in the Manager tab. You can then launch it from there.

Logging

The following methods are available from the Task class for logging:

public void Info(string msg);
public void InfoFormat(string msg, params object[] args);
public void Debug(string msg);
public void DebugFormat(string msg, params object[] args);
public void Error(string msg);
public void ErrorFormat(string msg, params object[] args);
public void Error(string msg, Exception e);
public void ErrorFormat(string msg, Exception e, params object[] args);

Files

Files can be loaded in a task by calling the methods Add or AddRange:

this.Files.Add(myFile);
this.Files.AddRange(myFiles);

Then the files loaded can be selected in other tasks by their task Id as follows:

<Setting name="selectFiles" value="$taskId" />

To select the files loaded by the running instance of a workflow through the selectFiles settings option, you can do it as follows:

FileInf[] files = this.SelectFiles();

State is transferred between tasks through selectFiles and through selectEntities settings.

This works the following way:

  1. A task in a workflow does its job and produces files which it stores in a collection.
  2. Another task (must be in the same workflow) can afterwards reference those files with the selectFiles setting, specifying the ID of the task that produced the required files. It then can use these files to do its own job.

More visually (from the examples):

<Workflow xmlns="urn:wexflow-schema" id="1" name="Workflow_Invoices" description="Workflow_Invoices">
    <Settings>
        <Setting name="launchType" value="trigger" />
        <Setting name="enabled" value="true" />
    </Settings>
    <Tasks>
        <Task id="1" name="FilesLoader" description="Loading invoices" enabled="true">
            <Setting name="folder" value="C:\WexflowTesting\Invoices\" />
        </Task>
        <!-- some more tasks here -->
        <Task id="6" name="FilesMover" description="Moving invoices" enabled="true">
            <Setting name="selectFiles" value="1" />
            <Setting name="destFolder" value="C:\WexflowTesting\Invoices_sent\" />
        </Task>
    </Tasks>
</Workflow>

Entities

Entity is an abstract class having the Id of the task as property:

namespace Wexflow.Core
{
    public abstract class Entity
    {
        public int TaskId { get; set; }
    }
}

The entity class is designed to be inherited by other classes such as objects retrieved from a database or a web service or an API for example. Then, these objects can be loaded in a task by calling the methods Add or AddRange:

this.Entities.Add(myEntity);
this.Entities.AddRange(myEntities);

Then, the entities loaded can be selected in other tasks by their task Id as follows:

<Setting name="selectEntities" value="$taskId" />

Entities are designed to be used in custom tasks.

To select entities loaded by the running instance of a workflow through the selectEntities settings option, you can do it as follows:

Entity[] entities = this.SelectEntities();

The Entity class could be very useful when working with custom tasks that manipulate objects from a database or Web Services for example.

Shared Memory

Tasks contains a shared memory between them.

To add an object to the shared memory, simply proceed as follows:

this.SharedMemory.Add("myKey", myObject);

To retrieve an object from the shared memory, simply proceed as follows:

var myObject = this.SharedMemory["myKey"];

To remove an object from the shared memory, simply proceed as follows:

this.SharedMemory.Remove("myKey");

History

  • 22 May 2020: Initial version.

License

This article, along with any associated source code and files, is licensed under The MIT License

Share

About the Author

Akram El Assas
Architect
Morocco Morocco
Akram graduated from the french engineering school ENSEIRB located in Bordeaux, a city in the south of France, and got his diploma in software engineering in 2010. He worked in France for Mediatvcom, a company specialized in audiovisual, digital television and new technologies. Mediatvcom offers services such as consulting, project management, audit and turnkey solutions adapted to the needs of customers. Akram worked mainly with Microsoft technologies such as C#, ASP.NET and SQL Server but also with JavaScript, jQuery, HTML5 and CSS3. Akram worked on different projects around digital medias such as Media Asset Management systems, Digital Asset Management systems and sometimes on HbbTV apps.

Comments and Discussions

 
GeneralMy vote of 5 Pin
HavenTech1 hr 6mins ago
MemberHavenTech1 hr 6mins ago 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Article
Posted 22 May 2020

Tagged as

Stats

2.7K views
2 bookmarked